最近闲的蛋疼,了解一些quick,装的是quick3.3windows版本,尝试在LUA脚本层使用protobuf协议。谷歌官方已经推出了很多种语言的版本。但唯独LUA版本不全。于是百度(狗日的党)一些帖子开始研究protobuf在LUA下的实现,将过程记录了下来,希望对其它人能有所帮助。
1、下载protoc-gen-lua
可以通过HG从服务器(hg clone https://code.google.com/p/protoc-gen-lua/)上下载最新的版本。
简单介绍一下里面的三个目录:
example 存放的一个示例协议,
plugin 将.proto协议转为LUA脚本需要的工具。要注意,这个工具是用PYTHON写的,所以后面我们需要安装PYTHON。
rotobuf这里存放了工程需要的文件。其中pb.c是C码文件。主要是在工程中引用,也可以编译成动态文件(.so)供LUA调用。其它LUA文件则需要引入到LUA工程中。
2、安装PYTHON27。推荐是这个版本,一定要2.7.5到3.0之间的版本,切记切记。
3、下载protobuf然后编译出protoc.exe。
可以用SVN从服务器上(http://protobuf.googlecode.com/svn/trunk)下载最新的protobuf。我使用的是protobuf3。
进入protobuf/vsprojects利用VS2012进行编译。生成的protoc.exe放到protobuf/src下。如果不放,后面无法安装python版的protobuf。
4、编译python版本的protobuf
在protobuf\python下运行python setup.py build,然后再执行python setup.py install。
注意:如果第3步的protoc.exe没有放,会出现错误找不到google\protobuf\compiler目录。
5、制作转换协议的批处理
在protoc-gen-lua/plugin目录下编写批处理:protoc-gen-lua.bat,就下面一行代码。
///////////////////////////////////////////////////////////////////////////////////////
@python “%~dp0protoc-gen-lua”
///////////////////////////////////////////////////////////////////////////////////////
但要确保你的python命令能正常运行。否则将python.exe所在的目录加到环境变量path中。
6、生成你的pb文件
// goat.proto
message Login_C2S_Msg{
required int32 aaa = 1; //
}
通过:protoc.exe --plugin=protoc-gen-lua=".protoc-gen-lua.bat" --lua_out=. goat.proto 产生 lua 使用的 ‘goat_pb.lua’文件
- 重新编译quick3的player
这一步不做的话,会报
这样的错误。
protoc-gen-lua/protobuf目录中有一个pb.c文件,把它拷贝到 quick-3.3\quick\lib\quick-src\lua_extensions 目录下,我这边在lua_extensions新建一个protobuf文件夹,把pb.c拷贝进去。
修改当前目录的lua_extensions_more.c文件,
修改1,在lsqlite3加上pb.c
// lsqlite3
#include “lsqlite3/lsqlite3.h”
// protobuf
#include “protobuf/pb.c”
修改2, 在lua_pop(L,2)后注册pb
lua_pop(L, 2);
luaopen_pb(L); // protobuf 扩展注册
pb.c文件有一处引用错误,把#include <endian.h> 修改成 #ifndef _WIN32 #include <endian.h> #endif
用vs2012打开quick-3.3\quick\player\proj.win32\player.vcxproj 进行编译就OK了
8、开始测试
新建一个quick项目,在src中建立一个目录pb,把protoc-gen-lua\protobuf下面的所有lua文件拷贝过来 ,我比较懒,把产生的goat_pb.lua也扔过来了,你们一定不要这么做。
打开项目main.lua增加包路径: package.path = package.path … “;src/pb/?.lua”
MainScene.lua中开头引入,(很多人在函数中引入,属于延迟加载是吗,原谅我是个java猿):
require(“pb”)
require(“goat_pb”)
可以在架构体或者onEnter里加下面几句测试:
local msg = goat_pb.Login_C2S_Msg()
msg.aaa = 111
local data = msg:SerializeToString()
print(data)
print(“dddddddd”)
local msg2 = goat_pb.Login_C2S_Msg()
msg2:ParseFromString(data)
print("parser:", msg2.aaa)
print("ttttttt")
跑起来,跑起来,然后会打印:
o
dddddddd
parser:111
tttttttt
大功告成!