Lua 中实现 protobuf 序列化,反序列化

转自:http://blog.****.net/fanyun7654/article/details/52596000


Protobuf 官方并没有 Lua版本,然后网易的程序猿开发出了 protoc-gen-lua ,可以让我们将 Proto 文件转成 lua 脚本在 Lua中使用,下面是详细的编译、安装、使用教程。文中用到的代码、工具都有百度网盘下载。

网盘下载地址: http://pan.baidu.com/s/1bo8Ufd9  

1、首先我们需要安装Python2.7,下载地址:

[html] view plain co
默认安装到C盘

Lua 中实现 protobuf 序列化,反序列化

把安装目录添加到环境变量中,然后打开命令行 控制台,输入命令

[html] view plain copy
 
 Lua 中实现 protobuf 序列化,反序列化Lua 中实现 protobuf 序列化,反序列化
  1. python  

如果提示 命令不存在,则说明环境变量没有设置正确,如果是如下图,说明设置成功  

ame.com.cn

2、下载并编译 Luajit 2.0.4 ,

下载后解压,找到 LuaJIT-2.0.4/src  目录,其中有一个批处理文件 msvcbuild.bat ,这是在 Windows系统的编译工具。

在开始菜单 - 所有应用中的 Visual Studio 201x 中找到 Visual Studio Tools,打开 VS201x 开发人员命令提示,切换到 LuaJIT-2.0.4/src 目录,执行命令

[html] view plain copy
 
 Lua 中实现 protobuf 序列化,反序列化Lua 中实现 protobuf 序列化,反序列化
  1. msvcbuild.bat  

开始编译 Luajit 2.0.4

Lua 中实现 protobuf 序列化,反序列化


像下图 出现 Successfully built LuaJIT for Windows/x86  说明编译成功

Lua 中实现 protobuf 序列化,反序列化

本文转自http://blog.****.net/huutu http://www.thisisgame.com.cn

到 LuaJIT-2.0.4\src 目录中寻找  lua51.dll  lua51.lib  luajit.exe 这三个文件是否存在,如果上面编译成功,那这三个文件是一定有的。

Lua 中实现 protobuf 序列化,反序列化


3、下载并编译 protobuf-2.4.1 

在 protobuf-2.4.1\vsprojects 目录中打开 protobuf.sln ,如下图

Lua 中实现 protobuf 序列化,反序列化


在 Visual Studio 中将 下图中 红框 中的 test 项目 从项目中移除,要来没用。

Lua 中实现 protobuf 序列化,反序列化


删除后如下图

Lua 中实现 protobuf 序列化,反序列化


项目一个一个编译,不要一起编译。

首先来编译 libprotobuf 项目肯定会出错。提示如下错误

Lua 中实现 protobuf 序列化,反序列化


原因是Protobuf 中没有添加对应的头文件,在项目中 搜索打开 common.h ,添加对应头文件,如下图:

Lua 中实现 protobuf 序列化,反序列化

再次编译,就可以编译成功。


然后编译 第二个项目 libprotobuf-lite 。不会出错。


然后再编译 第三个项目 libprotoc 。肯定会出错,如下图  

Lua 中实现 protobuf 序列化,反序列化


双击定位错误,或者打开 command_line_interface.cc ,到913行 ,修改为如下图

Lua 中实现 protobuf 序列化,反序列化


再次编译,即可成功。


最后编译第四个 项目 protoc 。编译成功

然后到 protobuf-2.4.1\vsprojects\Debug 目录中找到生成的 4 个文件,如下图红框中的文件

Lua 中实现 protobuf 序列化,反序列化


这4个文件会在 编译 protoc-gen-lua的时候用到。


编译成功后,到 protobuf-2.4.1\Python 文件夹中执行命令

[html] view plain copy
 
 Lua 中实现 protobuf 序列化,反序列化Lua 中实现 protobuf 序列化,反序列化
  1. python setup.py install  

4、下载并 编译安装 protoc-gen-lua ,   

下载解压后,打开 目录,如下图有三个文件夹

Lua 中实现 protobuf 序列化,反序列化


在 plugin 目录 创建 批处理文件 protoc-gen-lua.bat  , 内容如下

[csharp] view plain copy
 
 Lua 中实现 protobuf 序列化,反序列化Lua 中实现 protobuf 序列化,反序列化
  1. @python "%~dp0protoc-gen-lua"  

然后将 上一步 编译 protobuf-2.4.1 中生成的 protoc.exe 拷贝到  protoc-gen-lua-master 目录,如下图

Lua 中实现 protobuf 序列化,反序列化


然后在 protoc-gen-lua-master 目录下创建批处理文件  buildproto.bat ,内容如下

[csharp] view plain copy
 
 Lua 中实现 protobuf 序列化,反序列化Lua 中实现 protobuf 序列化,反序列化
  1. rem 切换到.proto协议所在的目录  
  2. cd  protobuf\luascript  
  3. rem 将当前文件夹中的所有协议文件转换为lua文件  
  4. for %%i in (*.proto) do (    
  5. echo %%i  
  6. "..\..\protoc.exe" --plugin=protoc-gen-lua="..\..\plugin\protoc-gen-lua.bat" --lua_out=. %%i  
  7.   
  8. )  
  9. echo end  
  10. pause  

这个批处理的作用是:先进入到一个文件夹,然后将该文件夹中的 proto  文件 生成 lua 文件。 我这里是进入到 protoc-gen-lua-master\protobuf\luascript 。

所以我在 protobuf 目录下新建 目录 luascript   ,在该目录进行 proto 转换 lua 。如果需要在其它目录进行,要把上面批处理的内容修改目录为自己想要的。


好,下面来测试一下。

在 protoc-gen-lua-master\example  目录下有一个测试的 proto 文件 person.proto ,把它拷贝到  luascript 文件夹。

Lua 中实现 protobuf 序列化,反序列化

然后 返回执行上面创建的批处理文件 buildproto.bat 。 本文转自http://blog.****.net/huutu http://www.thisisgame.com.cn

Lua 中实现 protobuf 序列化,反序列化


生成成功,到  luascript 中查看,看到生成了对应的 lua 文件 person_pb.lua 。

Lua 中实现 protobuf 序列化,反序列化



5、编写工程测试 生成的 protobuf lua 文件

新建一个空项目,把 protoc-gen-lua-master\protobuf\pb.c  加入到项目中。

Lua 中实现 protobuf 序列化,反序列化


在 main.cpp 中添加初始化 Lua 以及初始化 proto-lua 的代码

[cpp] view plain copy
 
 Lua 中实现 protobuf 序列化,反序列化Lua 中实现 protobuf 序列化,反序列化
  1. #ifdef _WIN32  
  2. #include<windows.h>  
  3. #endif  
  4.   
  5. extern "C"  
  6. {  
  7. #include <lua.h>    
  8. #include <lualib.h>    
  9. #include <lauxlib.h>    
  10. int luaopen_pb(lua_State *L);  
  11. }  
  12.   
  13.   
  14. int main(int argc, char* argv[])  
  15. {  
  16.   
  17.     lua_State *L = lua_open();  
  18.     luaL_openlibs(L);  
  19.     luaopen_pb(L);  
  20.     luaL_dofile(L, "main.lua");  
  21.     lua_pcall(L, 0, LUA_MULTRET, 0);  
  22.     lua_close(L);  
  23. #ifdef _WIN32  
  24.     system("pause");  
  25. #endif  
  26.     return 0;  
  27. }  


设置 头文件引用路径为  LuaJIT-2.0.4\src 目录

设置链接器附加库目录为 LuaJIT-2.0.4\src 目录

设置链接器附加依赖项为 lua5.1.4.lib 

然后编译,肯定会报错。。如下图

Lua 中实现 protobuf 序列化,反序列化


需要修改 pb.c 的开始部分代码如下

Lua 中实现 protobuf 序列化,反序列化

就是用 宏定义 来判断,在Windows 系统下不引用 endian.h 这个文件。

再次编译,肯定成功。

在上面的代码中,我们加载了一个 lua 脚本文件 main.lua 。

我们在项目目录中新建 main.lua 并添加如下代码

[cpp] view plain copy
 
 Lua 中实现 protobuf 序列化,反序列化Lua 中实现 protobuf 序列化,反序列化
  1. package.path = package.path .. ';./protobuf/?.lua;./protobuf/luascript/?.lua'    
  2.   
  3. require "Person_pb"  
  4.   
  5. local msg = Person_pb.Person()  
  6. msg.id = 100  
  7. msg.name = "foo"  
  8. msg.email = "bar"  
  9.   
  10. local pb_data = msg:SerializeToString()  -- Parse Example  
  11.   
  12. print("create:", msg.id, msg.name, msg.email, pb_data)  
  13.   
  14. local msg1 = Person_pb.Person()  
  15. msg1:ParseFromString(pb_data)  
  16. print("parser:", msg1.id, msg1.name, msg1.email, pb_data)   

在 lua 代码里面,我们 测试了 对 person 的序列化 和 反序列化 。


还记得之前生成的 person_pb.lua 文件吗?在 protoc-gen-lua-master\protobuf\luascript 目录里。

我们把整个 protoc-gen-lua-master\protobuf 目录拷贝到测试项目 目录 里来。因为 main.lua 中要引用这些 lua 文件。

Lua 中实现 protobuf 序列化,反序列化


然后运行测试项目

Lua 中实现 protobuf 序列化,反序列化


序列化 和 反序列化 测试成功

测试工程下载

[html] view plain copy
 
 Lua 中实现 protobuf 序列化,反序列化Lua 中实现 protobuf 序列化,反序列化
  1. http://pan.baidu.com/s/1ntvlBp3  


至此, protoc-gen-lua 编译 测试使用完毕