Lua环境下对Protobuf的序列化与反序列化

关于Protobuf的介绍,这里不过多叙述,只介绍Lua环境下对Protobuf的使用

Protobuf官方并未支持Lua环境下的使用,于是许多第三方库应运而生,这边介绍两种较为常用的库lua-protobufprotoc-gen-lua

环境安装

安装官方protobuf

git下载项目至本地,这里通过Python方式安装:

  1. 安装Python2.7
  2. 命令行安装protobuf

    python ./python/setup.py install

测试用例

hello.proto

syntax = "proto2";

package hello;

message Phone {
    required string name = 1;
    optional int64 phonenumber = 2;
}
message Person {
    required string name = 1;
    required int32 age = 2;
    optional string address = 3;
    repeated Phone contacts = 4;
}

protoc-gen-lua

这是一个比较老牌的库,但是由于采用懒惰加载的形式,只能通过set、get来读取解析,加上长期无人维护,导致官方版本有许多BUG,因此不推荐使用

放上一个自用的版本,修复了一些BUG,可以保证正常使用

github:https://github.com/GrayGuardian/protoc-gen-lua

测试环境

Unity 2019.3.4f + tolua

tolua自带有protoc-gen-lua,可以直接使用

如果希望使用xlua,需要自行编译扩展库,详见下方lua-protobuf测试环境的搭建

pb导出

protoc-gen-lua所使用的pb文件是一个*.lua

[库项目目录]\protobuf-lua\protoc.exe --plugin=protoc-gen-lua="[库项目目录]\protobuf-lua\plugin\protoc-gen-lua5_3.bat"  --lua_out=[lua文件输出目录] -I [protobuf依赖文件目录] [protobuf文件路径]

示例

导出pb文件

[库项目目录]\protobuf-lua\protoc.exe --plugin=protoc-gen-lua="[库项目目录]\protobuf-lua\plugin\protoc-gen-lua5_3.bat"  --lua_out=D:\protoc-gen-lua -I D:\protoc-gen-lua D:\protoc-gen-lua\hello.proto

Lua调用

-- 这里由于protoc-gen-lua对repeated int64的支持不好,最高只能到2147483648,所以测试用例电话号码改为2147483647
local data = { name= "胡汉三", age= 43, contacts= {{ name= "小马哥", phonenumber=2147483647 }, { name="小马哥" }} };
local pb = require("hello_pb")
-- 序列化
local person = pb.Person();
person.name = data.name;
person.age = data.age;
local phone1 = person.contacts:add();
phone1.name = data.contacts[1].name;
phone1.phonenumber = data.contacts[1].phonenumber;
local phone2 = person.contacts:add();
phone2.name = data.contacts[2].name;

local buff = person:SerializeToString()
print('序列化成功',buff)
-- 反序列化
local person = pb.Person();
person:ParseFromString(buff)
print('反序列化成功',person.name,person.contacts[1].phonenumber);

lua-protobuf

相对于protoc-gen-lua来说使用,更方便更稳定,推荐使用

github:https://github.com/starwing/lua-protobuf

测试环境

Unity 2019.3.4f + xlua

xlua自身并不携带lua-protobuf,需要自行编译扩展第三方库,可以见Windows平台下的XLua第三方库的扩展编译

pb导出

lua-protobuf所使用的pb文件就是官方所生成的二进制文件

protoc.exe -o [pb文件路径] [protobuf文件路径]

示例

导出pb文件

为了方便导出,使用上方protoc-gen-lua库中的官方python库

D:\protoc-gen-lua\protobuf-python\protoc.exe -o hello_pb.bytes hello.proto

Lua调用

-- 这里直接通过C#加载pb字节流
local pbBuff = CS.System.IO.File.ReadAllBytes('D:\\protoc-gen-lua\\hello_pb.bytes')
local pb = require('pb')
pb.load(pbBuff)

local data = { name= '胡汉三', age= 43, contacts= {{ name= '小马哥', phonenumber=13666556464 }, { name='小马哥' }} };

-- 序列化
local buff = assert(pb.encode('hello.Person', data))
print('序列化成功',buff,pb.tohex(buff))
-- 反序列化
local person = assert(pb.decode('hello.Person',buff))
print('反序列化成功',person.name,person.contacts[1].phonenumber);