xLua下使用lua-protobuf
本文发表于程序员刘宇的博客,转载请注明来源: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的更多相关文章
- 腾讯开源手游热更新方案,Unity3D下的Lua编程
原文:http://www.sohu.com/a/123334175_355140 作者|车雄生 编辑|木环 腾讯最近在开源方面的动作不断:先是微信跨平台基础组件Mars宣布开源,腾讯手游又于近期开源 ...
- mac下搭建lua环境
mac下安装lua(可借助:rudix 地址:http://rudix.org) curl -s https://raw.githubusercontent.com/rudix-mac/rpm/201 ...
- CentOS下编译Lua使得其支持动态链接
在Linux下编译Lua时,我一般都是使用的make generic,这样编译没有什么问题,运行lua的程序也都OK,但是,这样在加载外部的C动态 链接库,却总是报下面的错误 dynamic libr ...
- 在Windows和MacOS下编译Lua
官方说明: http://www.lua.org/manual/5.3/readme.html 在Windows下编译Lua动态链接库的注意事项: 1. 创建一个空的DLL项目: 2. 将src文件夹 ...
- 在Windows环境下构建Lua 入门
在Windows环境下构建Lua 一:准备软件 1.C-compiler(TDM GCC) http://tdm-gcc.tdragon.net/download 2.Lua源代码 http:// ...
- mac下Nginx+lua模块编译安装
Nginx的nb之处就不说了,lua也是一个小巧的脚本语言,由标准C编写而成,几乎可以运行在所有的平台上,也非常强大,其他特性请自行度娘.nginx_lua_module是由淘宝的工程师清无(王晓哲) ...
- windows下编译lua源码
所有的lua源码都放在了 src 文件夹下,当然,不同的lua版本目录结构有可能不一样,但是都会有 src 这个文件夹,只有这个才是我们编译必须的.而且lua越做越精简了,5.1的版本里面还有一些te ...
- 在C语言环境下使用google protobuf
本文写给经常使用C编程且不喜欢C++而又要经常使用google protobuf的人. 经常写通讯程序的人对数据进行序列化或者反序列化时,可能经常使用google的protobuf(PB ...
- 【转载】cocos2d-x教程 Mac系统下搭建Lua的编码环境
原文链接:http://blog.csdn.net/u012945598/article/details/17168831 在使用Lua写脚本的时候大家都会因为没有代码提示导致敲代码的效率有所下降 ...
随机推荐
- P1027 三角形的周长
题目描述 有n根棍子,棍子i的长度为Ai.现在想要从中选出3根棍子组成周长尽可能长的三角形.请输出最大周长,若无法组成三角形则输出0. 输入格式 第一行是一个正整数n(3<=n<=1000 ...
- linux 延后执行
设备驱动常常需要延后一段时间执行一个特定片段的代码, 常常允许硬件完成某个任务. 在这一节我们涉及许多不同的技术来获得延后. 每种情况的环境决定了使用哪种技术最好; 我们全都仔细检查它们, 并且指出每 ...
- linux 在 1 MB 之下的 ISA 内存
一个最著名的 I/O 内存区是在个人计算机上的 ISA 范围. 这是在 640 KB(0xA0000)和 1 MB(0x100000)之间的内存范围. 因此, 它正好出现于常规内存 RAM 中间. 这 ...
- React Mobile 搭建记录
__dirname 总是指向被执行 js 文件的绝对路径,./ 会返回你执行 node 命令的路径,例如你的工作路径. path.join()方法可以连接任意多个路径字符串.要连接的多个路径可做为参数 ...
- koa2--04.ejs模板引擎
首先在项目文件下使用cmd,输入:npm install --save koa-views ejs,将koa-views中间件和ejs模板引擎安装到文件中,并自动写入依赖 接在在index.js文件中 ...
- C#调用smtp邮件发送几个大坑
1.网易.新浪邮箱新增了一个叫“授权码”的东西,开通smtp服务时,必须开启授权码,并且邮件发送代码中也需要加上授权码,如下代码: //指定邮箱账号和密码,需要注意的是,这个密码是你在邮箱设置里开启服 ...
- c3p0连接池封装
在处理数据库事物时需要同一个Connection 但是dbcp无法获得 单独工具也显得繁琐,改进成c3p0工具类: package utils; import java.sql.Connectio ...
- 谷歌浏览器不能播放audio 报错Uncaught (in promise) DOMException
在2018年4月份发布的Chrome 66正式关掉了声音自动播放,也就是说<audio autopaly></audio> <video autoplay>< ...
- python函数不定长参数
def fun(a, b, *args): print(a) print(b) print(args) print("="*30) ret = a + b for i in arg ...
- 什么是激励函数 (Activation Function)
relu sigmoid tanh 激励函数. 可以创立自己的激励函数解决自己的问题,只要保证这些激励函数是可以微分的. 只有两三层的神经网络,随便使用哪个激励函数都可以. 多层的不能随便选择,涉及梯 ...