Quick-cocos2d-x 集成 google protobuf 方法

有人问到我了, 我分享一下方法。

如果感觉太乱请见谅, 几次编写后提交错误,内容被清空, 无奈只好本地用markdown规范编写, 贴到了论坛里。
如果你有密集恐惧症, 请移步 http://ablegao.me/posts/quick-cocos2d-x-protobuf.html , 这个地方看着会舒服一些。

##第一步 需要最新的protobuf 类库和解析程序。
https://github.com/sean-lin/protoc-gen-lua

   git clone https://github.com/sean-lin/protoc-gen-lua.git 到任意的一个地方

然后,可以得到重要的两个目录

   protoc-gen-lua/plugin/
   protoc-gen-lua/protobuf/

##第二步, 我们需要使用protoc —lua_out=. 这种方法, 将我们自己的*.proto 的文件解析成lua文件

plugin目录是提供将buffer 文件解析成lua 版本的类库, 需要python 支持。 如果已经编译了google 官方的protoc 那个程序, 只需要在系统PATH环境变量总追加plugin目录就好:

   export PATH={protoc-gen-lua DIR }/plugin:$PATH

关于protoc的编译另请google .

如果解析不出lua文件来, 可以手动志信一下plugin/protoc-gen-lua的程序, 他应该是+x 的权限(chmod +x plugin/protoc-gen-lua)

细节的安装步骤可以参考 https://code.google.com/p/protoc-gen-lua/

##第三步 , 将protobuf 集成到quick 中

protoc-gen-lua/protobuf/ 目录就是要编译到quick-cocos2d-x目录里面的部分。

现在, 我们只需要 protoc-gen-lua/protobuf/pb.c 这个文件

先确定自己的quick-cocos2d-x lua扩展目录:

./quick-cocos2d-x/lib/cocos2d-x/scripting/lua/lua_extensions/

所有lua 的c/c++现成扩展,都可以直接放到这里。

将pb.c这个文件复制到 lua_extension目录下, 最好独立一个目录, 免得扩展多了乱。

这是我的目录结构:

./quick-cocos2d-x/lib/cocos2d-x/scripting/lua/lua_extensions/protobuf/pb.c

然后开始修改扩展程序配置文件, lua_extensions.c

他的路径:
./quick-cocos2d-x/lib/cocos2d-x/scripting/lua/lua_extensions/lua_extensions.c

目前是一个不足60行的小文件, 我打算全部贴进来:

#include “lua_extensions.h”

#if __cplusplus
extern “C” {
#endif

// cjson
#include “cjson/lua_cjson.h”

// zlib
#include “zlib/lua_zlib.h”

// lpack
#include “lpack/lpack.h”

// socket
#include “socket/luasocket.h”
#include “socket/mime.h”
#include “socket/socket_scripts.h”

// filesystem
#include “filesystem/lfs.h”

// lsqlite3
#include “lsqlite3/lsqlite3.h”

#include “protobuf/pb.c” //引用protobuf 库文件

static luaL_Reg luax_exts] = {
{“cjson”, luaopen_cjson_safe},
{“zlib”, luaopen_zlib},
{“pack”, luaopen_pack},
{“socket.core”, luaopen_socket_core},
{“mime.core”, luaopen_mime_core},
{“lfs”, luaopen_lfs},
{“lsqlite3”, luaopen_lsqlite3},
{NULL, NULL}
};

void luaopen_lua_extensions(lua_State L)
{
// load extensions
luaL_Reg
lib = luax_exts;
lua_getglobal(L, “package”);
lua_getfield(L, -1, “preload”);
for (; lib->func; lib++)
{
lua_pushcfunction(L, lib->func);
lua_setfield(L, -2, lib->name);
}
lua_pop(L, 2);

 // load extensions script
 luaopen_socket_scripts(L);
 luaopen_pb(L);   //这是加入的protobuf 扩展注册名

}

#if __cplusplus
} // extern “C”
#endif

至此 , protobuf 扩展部分就算扩展完成了。

确认是否成功支持 , 可以在quick 项目最先被调用的lua文件中追加 require “pb” 做测试。

*但这时候通过protoc 转码后得到的lua文件还不能被解析。

##第四步 从项目中包含protobuf的 lua库

protoc-gen-lua/protobuf/这个目录下面, 还有大量的.lua文件, 是用来支持proto转码后的文件解析调用的。 不能少了这些文件。

复制protoc-gen-lua/protobuf文件夹 到项目中 scripts目录下。

目录结构应该是这样的:
/scripts/protobuf/*.lua

然后, 需要告诉框架,从哪里可以引用到它。

修改main.lua 在require(“appxxxxxx”) 上面 , 加入下面的代码:

package.path = package.path … “;./protobuf/?.lua;./scripts/protobuf/?.lua;”

这个方法, 能保证程序在被编译到手机之后仍然可以继续访问这个库。

***千万别把转码的proto文件放到/scripts/protobuf 目录里面.不信可以试试。

现在, 项目支持protobuf 文件的解析了。

##第五步 重新编译player-x

如果不习惯用player-x调试, 这个步骤不是必须的。

进入player-x qt源码目录 :

cd quick-cocos2d-x/player/proj.qt

使用qmake 文件执行quick-x.pro 文件

qmake ./quick-x.pro

继续:

make

等待结束, 将得到的quick-x-player文件,

放到:quick-cocos2d-x/player/bin/mac/ 目录下, 这样sublime text 装QuickXDev 扩展的直接可以用。

**如果是mac os 10.9 系统, 可能编译不过去player-x程序。 我遇到了这个问题。

会提示错误 pb.c:28:10: fatal error: ‘endian.h’ file not found

如果错误信息相同, 修改文件:

./quick-cocos2d-x/lib/cocos2d-x/scripting/lua/lua_extensions/protobuf/pb.c

查找行:

#include <endian.h>

临时变更为:

#include <machine/endian.h>

然后重新编译 player-x

make 就足够了

make

**player-x 编译完毕后, 千万要将endian.h 引用改回原来的 #include <endian.h> , 否则打包到手机的时候又回提示文件找不到了。

2赞

感谢分享

支持一下。

吐槽下论坛的文字编辑,能支持markdown就好了

谢谢分享~正好要用到!

晕,不支持 markdown 确实蛋疼

楼主有没有碰到过这种问题:A.proto里面引用B.proto里定义的消息时,用protoc-gen-lua无法解析,但把A.proto和B.proto文件合并成一个文件C.proto时,用protoc-gen-lua能解析?

https://github.com/seekagain/protoc-gen-lua/commit/c023f867224cda2a91711d841c2d60391f4487ba#
这里据说已经解决。

看了一下 解决方案和
http://blog.csdn.net/adamwu1988/article/details/30498859
差不多。

但是,我这边windows上测试 还是过不了啊? 难道是我的Lua的版本问题

我这边错误,大概找到原因了

原来 我在main.lua里写了
package.path = package.path … ‘;./protobuf/?.lua’
其他路径里也有一个 person_pb.lua

文件不多的话,手动合并两个proto文件也ok

楼主,有没有研究过原生cocos2d,而不是quick cocos的,开发环境是这样:win7 64 + 原生cocos2d + cocos code ide + protobuf + protoc-gen-lua的。主要是pb.c这个文件的处理,目前碰到无法找到pb.lua文件问题

支持一下。

quick-cocos2d-x/player/proj.qt,这个目录我怎么没有啊,你们的quick版本是多少?

第三部集成完成了但是说找不到pb,在 require ‘pb’的时候说找不到:
:31: module ‘pb’ not found:
no field package.preload’pb’]
no file ‘./pb.lua’
no file ‘/usr/local/share/luajit-2.0.3/pb.lua’
no file ‘/usr/local/share/lua/5.1/pb.lua’
no file ‘/usr/local/share/lua/5.1/pb/init.lua’
no file ‘/Users/admin/Documents/workproject/freedom/samples/luasocket/scripts/pb.lua’
no file ‘./protobuf/pb.lua’
no file ‘./scripts/protobuf/pb.lua’
no file ‘…/protobuf/pb.lua’
no file ‘./pb.so’
no file ‘/usr/local/lib/lua/5.1/pb.so’
no file ‘/usr/local/lib/lua/5.1/loadall.so’
no file ‘…/protobuf/pb.so’

是不是在集成.c文件之后需要重新编码 c代码?

到了第三步, require “pb” 找不到pb.lua

新人懵懂,望指点。

到了第三步, require “pb” 找不到pb.lua

新人懵懂,望指点

到了第三步, require “pb” 找不到pb.lua

新人懵懂,望指点

这个需要把pb.c 加到player工程中去。再编译player。

不是的。是因为调用了luaopen_pb(L) 后 :229: attempt to index field ‘Director’ (a nil value)

所有cocos2d-x 的原生接口都不能用了