本文发表于程序员刘宇的博客,转载请注明来源:https://www.cnblogs.com/xiaohutu/p/12168781.html

前言

protobuf作为一种通用套接字格式,各种插件里,最本质、最关键的就是基于二进制的两个操作:

1. 根据proto文件打包出二进制数据。

2. 根据二进制数据反串化出需要的数据格式。

所以其实在不同平台下需要的就是各自的解析库。作为跨平台的套接字,同版本二进制打包出来的格式必须完全一样,1里的proto文件一般也是要在项目开发中多平台通用,2里反串化的格式是当前语言和环境下的格式。在lua环境里,一般反串化出来的就是table。

由于官方并没有给lua支持,所以大家各自发挥,使用的比较多的有4种:

1. pbc-lua: 云风早期写的解析库,解析官方protoc.exe生成的pb,缺点是只解析一层。

2. sproto: 云风(真是孜孜不倦高产出)强推的第二版协议,其实已经不能完全说是proto,而是一种新套接字,只是兼容。这是他自己关于sproto的说明: https://blog.codingnow.com/2015/04/sproto_rpc.html

3. protoc-gen-lua: seanlin写的插件,这个大家用的也多,ulua,tolua的很多项目都用这个。原理是生成lua端的.lua描述文件,打包时先使用描述文件的定义来New,然后Serialize。只支持到5.1,后面就没有维护了。

4. lua-protobuf: 这个现在大家用的多,是目前在莉莉丝工作的starwing写的,这个使用起来也很简单,可以读pb,也可以直接读定义文件(性能捉急),然后直接在lua按照proto格式写table,encode就行了。

下面说说如何接入lua-protobuf插件,参考链接:

xLua官方:https://github.com/Tencent/xLua

xLua官方集成第三方库:https://github.com/chexiongsheng/build_xlua_with_libs

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

编库文件

1. 首先是要获得库文件,先去集成的git下查看一下版本,有一些已经编号的是否可以用,里面是根据xlua的版本来保存了一些编好的库,具体有ffi,lpeg,rapidjson,lua-protobuf,pbc(chexiongsheng大佬贴心)。

2. 没有现成的版本也没关系,我们把相关的库和xlua的源码一起编一下就行了。先拿下第三方库的svn,再把我们实际使用的那个版本的xlua源码下下来(如:https://github.com/Tencent/xLua/tree/master/build),拷到本地下好的build_xlua_with_libs文件夹里。然后根据平台分别编译.安卓下NDK,cmake,ninja,AndroidSDK,JDK统统安装好,点击make_android_lua53.bat,PC下的先安装好cmake和c++的vs环境,点击make_win64_lua53.bat,MAC下先"chmod 777 make_ios_lua53.sh",然后执行 "./make_ios_lua53.sh"。编完了以后plugin_lua53\Plugins下就有各平台的库文件啦。

把库文件加入项目

1. 使用xLua提供的加载静态库方法AddBuildin,这个方法可以指定在lua侧指定特定库文件名在C#端的加载方法,并且限定了格式:

 public void AddBuildin(string name, LuaCSFunction initer)
//name:buildin模块的名字,require时输入的参数;
//initer:初始化函数,原型是这样的public delegate int lua_CSFunction(IntPtr L),必须是静态函数,
//而且带MonoPInvokeCallbackAttribute属性修饰,这个api会检查这两个条件。

2. 接着我们在某个地方定义一下这个LuaCSFunction,一般是在LuaDLL.cs里,这里把luaopen_pb这个方法extern过来,写进了LoadPb里

 namespace LuaDLL
{
public partial class Lua
{
[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
public static extern int luaopen_pb(System.IntPtr L); [MonoPInvokeCallback(typeof(LuaDLL.lua_CSFunction))]
public static int LoadPb(System.IntPtr L)
{
return luaopen_pb(L);
}
}
}

3. 准备完毕后,在我们lua端的初始化的地方添加加载这个"pb"库的方法:

 LuaEnv luaenv = new LuaEnv();
luaenv.AddBuildin("pb", XLua.LuaDLL.Lua.LoadPb);
--luaenv.AddBuildin("rapidjson", XLua.LuaDLL.Lua.LoadRapidJson);

4. 这样的话在lua中再require 'pb'的时候就会自动调用pb库

 -- 加载pb文件
local pb = require "pb"

好了接下来就可以写网路框架代码了。

框架代码接入

1. 先加载proto结构定义,前面提到可以加载pb或者proto.Schema结构,分别如下:

第一种大家都熟悉,编一下pb文件,使用loadfile加载

 -- 加载pb文件,需要把proto编成pb使用
local pb = require "pb"
assert(pb.loadfile "login.pb")

第二种是我使用的,因为是Schema结构,做成文本文件方便结合资源系统更新

 local pb = require "pb"
local protoc = require "protoc" --protoc在lua-protobuf的目录里 local protoString = ResLoader.Instance:LoadLuaProtoFile('login.proto.txt') --用自己的资源系统加载文本格式文件
protoc:load(protoString) --加载文本文件的内容

2. 使用pb解码,编码协议。这一步就是标准的流程了,lua-protobuf可以直接对定义好的结构decode/encode:

 -- 定义表数据
local loginCS = {
username="jack",
password="",
} -- 序列化
local bytes = assert(pb.encode("login.req_login", loginCS))
print(pb.tohex(bytes)) -- 反序列化
local recvData = assert(pb.decode("login.req_login", bytes))
print(recvData .username)

到这就跟以前其他平台使用protobuf没有什么区别了,这篇入门到此结束。

 

xLua下使用lua-protobuf的更多相关文章

  1. 腾讯开源手游热更新方案,Unity3D下的Lua编程

    原文:http://www.sohu.com/a/123334175_355140 作者|车雄生 编辑|木环 腾讯最近在开源方面的动作不断:先是微信跨平台基础组件Mars宣布开源,腾讯手游又于近期开源 ...

  2. mac下搭建lua环境

    mac下安装lua(可借助:rudix 地址:http://rudix.org) curl -s https://raw.githubusercontent.com/rudix-mac/rpm/201 ...

  3. CentOS下编译Lua使得其支持动态链接

    在Linux下编译Lua时,我一般都是使用的make generic,这样编译没有什么问题,运行lua的程序也都OK,但是,这样在加载外部的C动态 链接库,却总是报下面的错误 dynamic libr ...

  4. 在Windows和MacOS下编译Lua

    官方说明: http://www.lua.org/manual/5.3/readme.html 在Windows下编译Lua动态链接库的注意事项: 1. 创建一个空的DLL项目: 2. 将src文件夹 ...

  5. 在Windows环境下构建Lua 入门

    在Windows环境下构建Lua 一:准备软件 1.C-compiler(TDM GCC)  http://tdm-gcc.tdragon.net/download 2.Lua源代码  http:// ...

  6. mac下Nginx+lua模块编译安装

    Nginx的nb之处就不说了,lua也是一个小巧的脚本语言,由标准C编写而成,几乎可以运行在所有的平台上,也非常强大,其他特性请自行度娘.nginx_lua_module是由淘宝的工程师清无(王晓哲) ...

  7. windows下编译lua源码

    所有的lua源码都放在了 src 文件夹下,当然,不同的lua版本目录结构有可能不一样,但是都会有 src 这个文件夹,只有这个才是我们编译必须的.而且lua越做越精简了,5.1的版本里面还有一些te ...

  8. 在C语言环境下使用google protobuf

    本文写给经常使用C编程且不喜欢C++而又要经常使用google protobuf的人.        经常写通讯程序的人对数据进行序列化或者反序列化时,可能经常使用google的protobuf(PB ...

  9. 【转载】cocos2d-x教程 Mac系统下搭建Lua的编码环境

    原文链接:http://blog.csdn.net/u012945598/article/details/17168831   在使用Lua写脚本的时候大家都会因为没有代码提示导致敲代码的效率有所下降 ...

随机推荐

  1. OpenWrt Kernel Module Creation Howto

    OpenWrt Kernel Module Creation Howto About OpenWrt Kernel Module Compilation You are planning to com ...

  2. Qt4与Qt3的主要不同

    Qt4与Qt3的主要不同 1)QT4 中提供了大量新控件,虽然它也保持了旧的控件,并命名为Qt3XXX,但是这样的控件没准在今后的哪个QT版本中就不被支持了,所以还是换吧,控件替换的 工作是巨大的,这 ...

  3. CodeForces 375D Tree and Queries

    传送门:https://codeforces.com/problemset/problem/375/D 题意: 给你一颗有根树,树上每个节点都有其对应的颜色,有m次询问,每次问你以点v为父节点的子树内 ...

  4. centos7 创建sftp

    sftp是Secure File Transfer Protocol的缩写,安全文件传送协议.可以为传输文件提供一种安全的网络的加密方法.sftp 与 ftp 有着几乎一样的语法和功能.SFTP 为  ...

  5. 错误 1 未能找到类型或命名空间名称“”, 引入DLL文件出现提示文件不存在问题

    在所有引入都正确的情况下,查看项目目标框架是否正确

  6. Python2_实现文件中特定内容的获取

    ===================================================== 参考链接 Python 文本文件内容批量抽取:https://blog.csdn.net/q ...

  7. 僵进程与SIGCHLD信号

    参考: https://www.cnblogs.com/webor2006/p/4014586.html wait()和waitpid()的参数解析:https://blog.csdn.net/csd ...

  8. 基于 HTML5 + WebGL 的无人机 3D 可视化系统

    前言 近年来,无人机的发展越发迅速,既可民用于航拍,又可军用于侦察,涉及行业广泛,也被称为“会飞的照相机”.但作为军事使用,无人机的各项性能要求更加严格.重要.本系统则是通过 Hightopo 的   ...

  9. docker-bind挂载

    使用绑定挂载 自Docker早期以来,绑定挂载一直存在.与卷相比,绑定装载具有有限的功能.使用绑定装入时,主机上的文件或目录将装入容器中.文件或目录由其在主机上的完整路径或相对路径引用.相反,当您使用 ...

  10. K8S中的ingress-nginx配置

    编辑在有道云笔记中,链接如下: http://note.youdao.com/noteshare?id=8d9ae3a1643e39714b36b58f7507baa2&sub=61C8C20 ...