lua-protobuf, 使用protobuf的Lua模块

分享于 

7分钟阅读

GitHub

  繁體
A Lua module to work with Google protobuf
  • 源代码名称:lua-protobuf
  • 源代码网址:http://www.github.com/starwing/lua-protobuf
  • lua-protobuf源代码文档
  • lua-protobuf源代码下载
  • Git URL:
    git://www.github.com/starwing/lua-protobuf.git
    Git Clone代码到本地:
    git clone http://www.github.com/starwing/lua-protobuf
    Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/starwing/lua-protobuf
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    
    Google protobuf支持Lua

    中文使用说明:https://zhuanlan.zhihu.com/p/26014103

    QQ群:485016061

    这个项目为基本的protobuf格式编码/解码提供了一个简单的C库。

    • pb.slice:有线格式解码模块。

    安装

    要安装这个Lua模块,你可以使用luarocks

    luarocks install lua-protobuf

    如果你想从源代码构建它,只需克隆repo,并使用luarocks:

    git clone https://github.com/starwing/lua-protobuf
    luarocks make rockspecs/lua-protobuf-scm-1.rockspec

    如果没有luarocks,请使用hererocks安装Lua和luarocks:

    pip install hererocks
    git clone https://github.com/starwing/lua-protobuf
    hererocks -j 2.0 -rlatest .bin/luarocks make lua-protobuf/rockspecs/lua-protobuf-scm-1.rockspec CFLAGS="-fPIC -Wall -Wextra" LIBFLAGS="-shared"cp protoc.lua pb.so ..

    或者你可以手动构建它,它只有一个纯Lua模块和一对C文件:pb.h和pb.c

    要在macOS上构建它,请使用你喜欢的编译器:

    gcc -O2 -shared -undefined dynamic_lookup pb.c -o pb.so

    在Linux上,使用几乎相同的命令:

    gcc -O2 -shared -fPIC pb.c -o pb.so

    在Windows上,可以使用MINGW或MSVC,创建sln项目或在命令行上生成它:

    cl /O2 /LD /Fepb.dll /I Lua53include /DLUA_BUILD_AS_DLL pb.c Lua53liblua53.lib

    例子

    local pb =require"pb"local protoc =require"protoc"assert(protoc:load[[ message Phone { optional string name = 1; optional int64 phonenumber = 2; } message Person { optional string name = 1; optional int32 age = 2; optional string address = 3; repeated Phone contacts = 4; } ]])local data = {
     name ="ilse",
     age =18,
     contacts = {
     { name ="alice", phonenumber =12312341234 },
     { name ="bob", phonenumber =45645674567 }
     }
    }local bytes =assert(pb.encode("Person", data))print(pb.tohex(bytes))local data2 =assert(pb.decode("Person", bytes))print(require"serpent".block(data2))

    用法

    protoc模块

    函数返回说明
    protoc.new() Proroc对象 创建新的编译器实例
    protoc.reload() true 将所有Google标准消息重新加载到PB模块中
    p:parse(string) 将架构转换为DescriptorProto
    p:parsefile(string)p:parse()类似,但接受文件名
    p:compile(string) 将架构转换为二进制*.pb格式数据
    p:compilefile(string)p:compile()类似,但接受文件名
    p:load(string) true 将架构加载到pb模块
    p:loadfile(string) true pb:loadfile()类似,但接受文件名
    p.loaded 包含所有已解析的DescriptorProto
    p.paths 表包含导入搜索目录
    p.unknown_module 请参见下文 处理架构导入错误
    p.unknown_type 请参见下文 处理架构中的未知类型
    p.include_imports 自动加载导入的proto

    要解析文本架构文件,应首先创建一个编译器实例:

    local p = protoc.new()

    然后,你可以将一些选项设置为编译器,例如搜索路径,未知处理程序,等等。

    p.paths[#p.paths+1] ="whatever/folder/hold/.proto/files"p.unknown_module=function(self, module_name) ...endp.unknown_type=function(self, type_name) ...endp.include_imports=true

    unknwon_moduleunknown_type句柄可以是true,string或函数,如果将它设置为true,则意味着所有不存在的模块或类型都被赋予一个默认值,并且不触发错误。如果将它设置为字符串,那么这个字符串是一个Lua模式,指示未知模块或类型是否应产生错误,例如,

    p.unknown_type="Foo.*"

    表示Foo前缀的所有类型都将视为exists类型,而不是触发错误。

    如果将这些处理程序设置为函数,则未知类型或模块名称将传递给函数,对于模块处理程序,应返回由p:load [file]()函数生成的DescriptorProto表,对于类型处理程序,应返回类型名称和类型,例如message或enum,

    function p:unknown_module(name)
     -- if can not find"foo.proto", load"my_foo.proto" insteadreturn p:load("my_"..name)endfunction p:unknown_type(name)
     -- if can not find"Type", treat it as".MyType" and is a message typereturn".My"..name, "message"end

    设置选项后,使用load[file]()compile[file]()parse[file]()函数获取结果。


    模块  proto  LUA  protobuf