概述我的cocos2d-x-3.2
集成云风pbc lua binding
方法 八月 19, 2014 | Posted by K-Res 关于protobuf的cocos2d-x lua的集成,参考过网上的一些资料,考虑过用google官方实现,但感觉过于臃肿,且没有直接的lua接口,实际应用需要做的框架级的工作较多,再有就是protoc-gen-lua(https://code.google 我的cocos2d-x-3.2集成云风pbc lua binding方法 八月 19,2014 | Posted by K-Res
关于protobuf的cocos2d-x lua的集成,参考过网上的一些资料,考虑过用Google官方实现,但感觉过于臃肿,且没有直接的lua接口,实际应用需要做的框架级的工作较多,再有就是protoc-gen-lua(https://code.google.com/p/protoc-gen-lua/),这个感觉就比较轻量了,但是还是有需要proto转换lua的前置 *** 作,另外就是据说某些protobuf的使用方式还不被支持,最后发现了云风做的一个实现:pbc(https://github.com/cloudwu/pbc)感觉思路很不错,而且有lua binding,决定尝试下cocos2d-x的集成。
参考百度到的两篇文章:
cocos2d-x 3.1 集成 云风pbc –http://www.jb51.cc/article/p-tzvlkppc-ea.html
在Quick-cocos2d-x中使用云风pbc解析Protocol Buffers –http://www.cnblogs.com/Erainbj/p/3618535.html
发现这些集成方法都是对cocos2d-x框架部分做了修改,可以说是直接从引擎底层进行了整合,而我则希望以上层应用代码的角度进行整合,这样在引擎升级时和其它项目复用时都能方便一些。
首先从最没有问题的平台入手,Mac和iOS,直接在Xcode项目中加入pbc的src和lua binding的pbc-lua.c并且设置好include搜索路径,当然,也可以用pbc源码中的Xcode项目预编译成库文件再引入,我还是倾向于对开源项目进行源代码整合,这样一旦发现问题还可以方便进行调试。然后在lua引擎加载入口脚本之前(默认是AppDelegate.cpp中),也就是
lua_State* lState = engine->getLuaStack()->getLuaState();
之后,加入pbc的lua函数注册:luaopen_protobuf_c(lState)。最后记得把protobuf.lua复制到cocos2d-x可以找到的位置,然后按着示例用.pb测试就可以了。
然后是Win平台,使用VS2013,添加好include还有所有src的引用编译后,遇到了编译不能通过的问题,看了一下错误,发现pbc的.c在VS中不能按C代码编译,而应该按照C++编译,在所有.c的属性页中的“C/C++ => 高级”中,设置“编译为C++代码”后编译通过。
最后是AndroID平台,按照项目结构和pbc源码的位置设置好mk文件中的src和include后,编译ok,但是运行时却出现了注册.pb文件出错的问题,看了一下pbc的lua代码,发现注册.pb文件是通过lua函数库中的io.open进行文件读取的,而cocos2d-x中的这部分的lua实现并没有重写过,就是直接封装的fopen,fread,fclose等,这样自然无法读取到被打包进AndroID asset文件夹中的.pb文件了!最开始考虑使用cocos2d-x的fileUtils替换掉pbc-lua中的io.open加载文件,想法就是既不修改cocos2d-x框架层的io.open实现,也不去重写pbc-lua的文件io *** 作,尽量都在用户应用层解决。看了一下fileUtils的lua导出,发现能够进行文件读取 *** 作的只有一个getStringFromfile可以用,测试了一下发现还是不能正常完成pbc-lua的注册pb *** 作,断点调试了一下fileUtils的getStringFromfile以及pbc-lua的相关实现代码,发现问题出在文件读取后的数据传递给lua的过程中,由于cocos2d-x直接实现getStringFromfile的lua-binding中,对加载后的const char*进行了lua_pushlstring(L,s,strlen(s))的 *** 作(由tolua的封装间接调用),而就是因为最后的strlen,导致读取.pb二进制文件时,错误的以文件中的0作为字符串结束标记错误的传递了整个二进制文件的长度,最终导致pbc-lua register时的错误。明确问题后解决就好办了,自己注册一个通过fileUtils实现的专门负责io二进制文件的c函数给lua调用:
1 | static int bsReadfile(lua_State *L) |
3 | const char *buff = luaL_checkstring(L,-1); |
4 | Data data = CCfileUtils::getInstance()->getDataFromfile(buff); |
5 | lua_pushlstring(L,( const char *)data.getBytes(),data.getSize()); |
6 | return 1; /* number of results */ |
11 | lua_register(tolua_S, "bsReadfile" ,bsReadfile); |
然后在pbc-lua注册pb时使用自己的io方法:
1 | pb = require "protobuf" |
2 | local pbfilePath = cc.fileUtils:getInstance():fullPathForfilename( "res/addressbook.pb" ) |
3 | cclog( "PB file path: " ..pbfilePath) |
4 | -- local f = assert (io.open(pbfilePath, "rb" )) |
5 | -- local buffer = f:read "*a" |
6 | local buffer = bsReadfile(pbfilePath) |
这样AndroID上就可以正常加载asset中的.pb文件了。
最后的最后,还有一个小问题,就是之前提到的VS需要将pbc的.c作为C++代码编译,这样就产生了一个问题:在其他平台上都是c方式编译的生成的符号都是c规范的,而win平台上则是c++规范的符号,用一样的调用代码的话,会导致找链接时找不到符号的问题,这个我的解决方法是分平台编译:
2 | #if CC_TARGET_PLATFORM != CC_PLATFORM_WIN32 |
5 | int luaopen_protobuf_c(lua_State *L); |
在win平台上以c++方式引用,其它平台以c方式引用。
Related posts: 更新Cocos2d-x 3.2 Spine runtime运行库到2.1以及相关lua binding的更新 deprecated conversion from string constant to char * 一篇Mac OS下的GL中glFlush和glFinish的区别解释 Get flicker free animation in MFC/GDI+
@H_419_517@
unclemiao 回复 K-Res: 无法解析的外部符号 _luaopen_protobuf_c,该符号在函数 "voID __cdecl quick_module_register(struct lua_State *)
4月17日 回复
顶
转发 @H_419_517@ K-Res
回复 unclemiao: 那这还是没有去掉extern "C"的效果,这是C方式的符号命名
总结
以上是内存溢出为你收集整理的我的cocos2d-x-3.2集成云风pbc lua binding方法全部内容,希望文章能够帮你解决我的cocos2d-x-3.2集成云风pbc lua binding方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
评论列表(0条)