cocos2d-x 3.x版本号变动比較大,从改用cmake管理整个项目,到使用python集成一体化的项目工具。

这些都是我喜欢的。我能够非常easy的在我的ubuntu上面搭建好开发环境,并且根本就不用考虑IDE的事情,sublime-text or emacs足矣。唯一须要自己动手的就是制作一个比較好的调试工具。我是使用lua+cplusplus开发,所以调试就比較的难受,临时仅仅能这样,后面考虑自己实现一个远程lua调试工具。

触控有公布一款IDE,但是眼下没有linux平台的版本号。我想以后也不会做的,所以就干脆胡忽略了吧。以下就说一下怎样在cocos2d-x
3.1里面集成pbc吧。

网上有关于怎样在quick-cocos2dx里面集成pbc的,只是quick和cocos2d-x的lua集成方式不一样,并且3.x的版本号在安卓平台使用的是luajit,只是在开发人员方面还是和lua一样。这仅仅是为了提高效率。

能够简单的看一下pbc中的lua binding以下的makefile,也是能够使用luajit的。假设对luajit感兴趣,那么就自己去搜罗吧。网上的这些关于集成pbc的文章,我有粗略的看过一些,结合cocos2d-x
3.x的情况,參考意义并不大,以下我也会给出我自己的做法。

我大三的时候写过一篇关于怎样在cocos2d-x中集成luasocket的文章,应该也算是比較早的了。只是。那篇文章的做法。在如今看来的确不是什么好方法,不值得推荐。

cocos2dx从2.x的某个版本号就加入了自己的lua loader,用来载入lua engine执行的脚本,详细可參考Cocos2dxLuaLoader.cpp/.h文件里的函数。

 1  int cocos2dx_lua_loader(lua_State *L)
2 {
3 std::string filename(luaL_checkstring(L, 1));
4 size_t pos = filename.rfind(".lua");
5 if (pos != std::string::npos)
6 {
7 filename = filename.substr(0, pos);
8 }
9
10 pos = filename.find_first_of(".");
11 while (pos != std::string::npos)
12 {
13 filename.replace(pos, 1, "/");
14 pos = filename.find_first_of(".");
15 }
16 filename.append(".lua");
17
18 Data data = FileUtils::getInstance()->getDataFromFile(filename);
19
20 if (!data.isNull())
21 {
22 if (luaL_loadbuffer(L, (char*)data.getBytes(), data.getSize(), filename.c_str()) != 0)
23 {
24 luaL_error(L, "error loading module %s from file %s :\n\t%s",
25 lua_tostring(L, 1), filename.c_str(), lua_tostring(L, -1));
26 }
27 }
28 else
29 {
30 log("can not get file data of %s", filename.c_str());
31 }
32
33 return 1;
34 }

假设想要实现对自己项目的lua脚本进行解密或者是解压缩处理,都能够在这里下一点功夫。会有不错的收获,这部分我在后面也会做。只是还在写加密算法中,还要再等等。 - -

或许我这里给出的函数仅仅是个開始。准确的说应该是个错误的開始。不要尝试从这里思考。

为什么? 由于cocos2d-x改动了lua的文件载入器。

详细的原因是lua在5.1版本号以后完好了管理机制。

採用统一的require载入,这也不难在cocos2d-x里面看出来。能够随便看看Lua引擎入口载入运行的函数,例如以下:(CCLuaStack.cpp)

 1 int LuaStack::executeScriptFile(const char* filename)
2 {
3 #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
4 std::string code("require \"");
5 code.append(filename);
6 code.append("\"");
7 return executeString(code.c_str());
8 #else
9 std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename);
10 ++_callFromLua;
11 int nRet = luaL_dofile(_state, fullPath.c_str());
12 --_callFromLua;
13 CC_ASSERT(_callFromLua >= 0);
14 // lua_gc(_state, LUA_GCCOLLECT, 0);
15
16 if (nRet != 0)
17 {
18 CCLOG("[LUA ERROR] %s", lua_tostring(_state, -1));
19 lua_pop(_state, 1);
20 return nRet;
21 }
22 return 0;
23 #endif
24 }

假设你须要写自己的脚本资源管理模块,那么这里就须要注意了。在android和其它平台处理的时候有明显的不同。不过不过在入口的不同,在兴许的require载入中都是一样的。由于在注冊

lua loader(也就是上面的cocos2dx_lua_loader)是一样的。

- - 当作一个友善的提示吧。然而lua本身提供的lua loader有四个,用于载入,在Lua源代码下的loadlib.c中能够找到:

1 static const lua_CFunction loaders[] =
2 {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};

相应luajit中也是能够找到的.源代码在luajit源代码文件夹下的lib_package.c中:

1 static const lua_CFunction package_loaders[] =
2 {
3 lj_cf_package_loader_preload,
4 lj_cf_package_loader_lua,
5 lj_cf_package_loader_c,
6 lj_cf_package_loader_croot,
7 NULL
8 };

经过cocos2d-x改动loader之后,lua在载入c lib的时候就有问题了,载入不到。

只是。还是能够通过改动lua的环境表来做到载入pbc。详细做法例如以下,改动lua_extension.c:

 1 #include "pbc-master/src/pbc-lua.h" //add
2
3 static luaL_Reg luax_exts[] = {
4 {"socket.core", luaopen_socket_core},
5 {"mime.core", luaopen_mime_core},
6 {"protobuf.c", luaopen_protobuf_c}, // add
7 {NULL, NULL}
8 };
9
10 void luaopen_lua_extensions(lua_State *L)
11 {
12 // load extensions
13 luaL_Reg* lib = luax_exts;
14 lua_getglobal(L, "package");
15 lua_getfield(L, -1, "preload");
16 for (; lib->func; lib++)
17 {
18 lua_pushcfunction(L, lib->func);
19 lua_setfield(L, -2, lib->name);
20 }
21 lua_pop(L, 2);
22 }

将下载的pbc源代码(假设是http下载的话那应该是pbc-master,假设是git clone的话那就是pbc)放到coco/lua文件夹以下去,将binding以下的pbc-lua.c复制到src文件夹以下。将pbc.h也相同拷贝过去,

然后在创建一个pbc-lua.h文件,内容就是luaopen_protobuf_c的函数声明,例如以下:

 1 #ifndef PBC_LUA_H
2 #define PBC_LUA_H
3
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7
8 extern int luaopen_protobuf_c(lua_State *L);
9
10 #ifdef __cplusplus
11 }
12 #endif
13
14 #endif/* PBC_LUA_H */

因为目标平台是安卓,所以以下就去改动ndk的Android.mk文件。目标就是coco/scripting/lua-bindings以下的Android.mk文件: 改动的部分例如以下:

 1 LOCAL_SRC_FILES := manual/CCLuaBridge.cpp \
2 manual/CCLuaEngine.cpp \
3 manual/CCLuaStack.cpp \
4 manual/lua_debugger.c \
5 manual/CCLuaValue.cpp \
6 manual/Cocos2dxLuaLoader.cpp \
7 manual/CCBProxy.cpp \
8 manual/Lua_web_socket.cpp \
9 manual/LuaOpengl.cpp \
10 manual/LuaScriptHandlerMgr.cpp \
11 manual/LuaBasicConversions.cpp \
12 manual/LuaSkeletonAnimation.cpp \
13 manual/lua_cocos2dx_manual.cpp \
14 manual/lua_cocos2dx_extension_manual.cpp \
15 manual/lua_cocos2dx_coco_studio_manual.cpp \
16 manual/lua_cocos2dx_ui_manual.cpp \
17 manual/lua_cocos2dx_spine_manual.cpp \
18 manual/lua_cocos2dx_physics_manual.cpp \
19 manual/lua_cocos2dx_deprecated.cpp \
20 manual/lua_xml_http_request.cpp \
21 manual/platform/android/CCLuaJavaBridge.cpp \
22 manual/platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge.cpp \
23 manual/tolua_fix.cpp \
24 manual/lua_extensions.c \
25 auto/lua_cocos2dx_auto.cpp \
26 auto/lua_cocos2dx_extension_auto.cpp \
27 auto/lua_cocos2dx_studio_auto.cpp \
28 auto/lua_cocos2dx_ui_auto.cpp \
29 auto/lua_cocos2dx_spine_auto.cpp \
30 auto/lua_cocos2dx_physics_auto.cpp \
31 ../../../external/lua/tolua/tolua_event.c \
32 ../../../external/lua/tolua/tolua_is.c \
33 ../../../external/lua/tolua/tolua_map.c \
34 ../../../external/lua/tolua/tolua_push.c \
35 ../../../external/lua/tolua/tolua_to.c \
36 ../../../external/lua/luasocket/auxiliar.c \
37 ../../../external/lua/luasocket/buffer.c \
38 ../../../external/lua/luasocket/except.c \
39 ../../../external/lua/luasocket/inet.c \
40 ../../../external/lua/luasocket/io.c \
41 ../../../external/lua/luasocket/luasocket.c \
42 ../../../external/lua/luasocket/mime.c \
43 ../../../external/lua/luasocket/options.c \
44 ../../../external/lua/luasocket/select.c \
45 ../../../external/lua/luasocket/serial.c \
46 ../../../external/lua/luasocket/tcp.c \
47 ../../../external/lua/luasocket/timeout.c \
48 ../../../external/lua/luasocket/udp.c \
49 ../../../external/lua/luasocket/unix.c \
50 ../../../external/lua/luasocket/usocket.c \
51 ../../../external/lua/pbc-master/src/alloc.c \ -- begin
52 ../../../external/lua/pbc-master/src/array.c \
53 ../../../external/lua/pbc-master/src/bootstrap.c \
54 ../../../external/lua/pbc-master/src/context.c \
55 ../../../external/lua/pbc-master/src/decode.c \
56 ../../../external/lua/pbc-master/src/map.c \
57 ../../../external/lua/pbc-master/src/pattern.c \
58 ../../../external/lua/pbc-master/src/proto.c \
59 ../../../external/lua/pbc-master/src/register.c \
60 ../../../external/lua/pbc-master/src/rmessage.c \
61 ../../../external/lua/pbc-master/src/stringpool.c \
62 ../../../external/lua/pbc-master/src/varint.c \
63 ../../../external/lua/pbc-master/src/wmessage.c \
64 ../../../external/lua/pbc-master/src/pbc-lua.c \ -- end

之后就不须要不论什么的改动了。也不须要在c++代码部分手动去载入pbc的库,由于一切都已经昨晚了。能够非常easy的看出来,这样的做法的优点。PS:最后别忘记将protobuf.lua复制到你的src或者是res以下,都是能够的,这个就不须要解释了。

測试是我将addressbook.pb复制到src文件夹以下,在AppDelegate.cpp中加入了比較简单的拷贝代码,将addressbook.pb复制到writablepath,原因就是后面我使用了lua io库去读pb文件。这也是直接參考pbc中的小样例写的,假设有更好的做法请告诉我。谢谢。

1  ssize_t __len = 0;
2 auto writablepath = FileUtils::getInstance()->getWritablePath()+"addressbook.pb";
3 unsigned char *data = FileUtils::getInstance()->getFileData("assets/src/addressbook.pb","r",&__len);
4
5 FILE *fp = fopen(writablepath.c_str(),"w");
6 fwrite(data,sizeof(char),__len,fp);
7 fclose(fp);
8 delete[] data;
9 data = NULL;

以下我给出lua部分的測试代码,实际执行是通过的,我的环境是ubuntu 14.04 x64 + ndk r9 + android

 1     local tf = cc.Label:create()
2 tf:setString(package.loaded)
3
4 local writablepath = cc.FileUtils:getInstance():getWritablePath()
5
6 local addr = io.open(writablepath .. "addressbook.pb", "rb")
7 local buffer = addr:read "*a"
8 addr:close()
9 protobuf.register(buffer)
10
11 local t = protobuf.decode("google.protobuf.FileDescriptorSet", buffer)
12 local proto = t.file[1]
13
14 tf:setString(proto.name .. " " .. proto.package)
15
16
17 local addressbook = {
18 name = "Alice",
19 id = 12345,
20 phone = {
21 { number = "1301234567" },
22 { number = "87654321", type = "WORK" },
23 }
24 }
25
26 local code = protobuf.encode("tutorial.Person", addressbook)
27
28 local decode = protobuf.decode("tutorial.Person" , code)
29
30 tf:setString(decode.name .. " | " .. decode.id)

我使用FileUtils:getInstance():getFileData无法获取数据,所以也就改为在C++那边拷贝,知道这部分怎样使用的能够告诉我。先谢过。

pbc lua binding 文摘:http://blog.csdn.net/kaitiren/article/details/28865725


cocos2d-x 3.1 集成 云风pbc的更多相关文章

  1. 在Quick-cocos2dx中使用云风pbc解析Protocol Buffers,支持win、mac、ios、android

    本例主要介绍 如何将 pbc 集成到quick-cocos2dx框架中,让我们的cocos2dx客户端Lua拥有编解码Protocol Buffers能力. 参考: 云风pbc的用法: http:// ...

  2. 云风pbc源码alloc.c

    #include <stdlib.h> #include <stdio.h> // 用于统计内存的申请和释放次数匹配 ; void * _pbcM_malloc(size_t ...

  3. 对云风 cstring 第二次解析

    前言 从明天起 关心粮食和蔬菜 我有一所房子 面朝大海 春暖花开 本文前提条件 1.了解 posix 线程 2.了解 原子操作 3.具备简单C基础,或者 你也敲一遍. 如果上面不太清楚,你可以翻看我以 ...

  4. 转:云风skynet服务端框架研究

    转:  http://forthxu.com/blog/skynet.html skynet是云风编写的服务端底层管理框架,底层由C编写,配套lua作为脚本使用,可换python等其他脚本语言.sky ...

  5. 云风协程库coroutine源码分析

    前言 前段时间研读云风的coroutine库,为了加深印象,做个简单的笔记.不愧是大神,云风只用200行的C代码就实现了一个最简单的协程,代码风格精简,非常适合用来理解协程和用来提升编码能力. 协程简 ...

  6. 【Serverless】快速集成云函数HarmonyOS

    ​1.学习目标 什么是AppGallery Connect云函数 云函数是一项Serverless计算服务,提供FaaS(Function as a Service)能力,可以帮助开发者大幅简化应用开 ...

  7. 转:c的回归-云风

    C 的回归 周末出差,去另一个城市给公司的一个项目解决点问题.回程去机场的路上,我用手机上 google reader 打发时间.第一眼就看到孟岩大大新的一篇:Linux之父话糙理不糙 .主题是 C ...

  8. C 的 coroutine 库 via 云风的 BLOG

    今天实现了一个 C 用的 coroutine 库. 我相信这个东西已经被无数 C 程序员实现过了, 但是通过 google 找了许多, 或是接口不让我满意, 或是过于重量. 在 Windows 下, ...

  9. 云风的BLOG❳可靠 UDP 传输

    http://mp.weixin.qq.com/s?__biz=MzA3NjYxOTA0MQ==&mid=405432715&idx=1&sn=2e40ceafd4b298e1 ...

随机推荐

  1. 帝国cms留言表模板修改

    <form action="../../enews/index.php" method="post" name="form1" id= ...

  2. 解决Qt程序发布时中文乱码问题(通过QApplication.addLibraryPath加载QTextCodec插件)

    Qt程序的文字编码,是通过插件来解决的,所以我们发布的时候需要把相应的插件也发布出去,在开发者电脑上程序会自动从插件目录加载到插件,但是如果发布给别的电脑使用,需要手动指定插件路径,如下所示: int ...

  3. 字符串匹配——Brute-Force 简单匹配算法

    下面几篇文章记录字符串匹配算法. Brute-Force算法简称BF算法,中文名叫简单匹配算法.正如其名,简单粗暴,按部就班地遍历所有字符,算法简单,效率低下,不被看好. 但也正因为不常用,反而容易生 ...

  4. 使用AFNetworking请求新浪微博数据接口出错解决办法

    在使用AFNetworking请求新浪微博数据接口时会出这样的错误,如 这样的错误说明,AFNetworking无法处理这样的数据格式.所以,我们需要修改AFNetworking中的一些接收数据格式. ...

  5. ebs清除并法管理器所清除的表

    In this Document   Goal   Solution   References Applies to: Oracle Concurrent Processing - Version 1 ...

  6. Choosing Between ElasticSearch, MongoDB &amp; Hadoop

    An interesting trend has been developing in the IT landscape over the past few years.  Many new tech ...

  7. leetcode 刷题之路 64 Construct Binary Tree from Inorder and Postorder Traversal

    Given inorder and postorder traversal of a tree, construct the binary tree. Note: You may assume tha ...

  8. Objective-C中的block块语法

    #import <Foundation/Foundation.h> /* OC不同于Java C++ 它没有字符串对象 只有NS对象 NS就是乔布斯第一个公司NeXt的类集合 被收购之后才 ...

  9. SAN实现

    Linux 上主要有三个 iSCSI Target(基于internet scsi协议的target) 实现: Linux SCSI Target – STGT / tgt Linux-IO Targ ...

  10. .Net 利用消息在进程间通讯实现进程互操作

    有时候我们会遇到需要在两个进程间通过某种方式实现互操作,方法有很多,例如你可以尝试让两个进程持续监视一个外部文件,由此文件记录各自进程的数据:还有可以使用网络端口实现进程间通讯.共享一片内存区域记录及 ...