最新文章
AppMobi发布HTML 5开发工具XDK
03-26 11:55
jqGrid的重要选项详解
03-26 11:52
解说HTML 5 语义化
03-26 11:50
HTML/CSS一些需要注意的基础知识
03-26 11:47
分享10个web前端简单实用的jQuery代码片段
03-26 11:42
分享七大无需编程的DIY开发工具
03-26 11:33
使用cocos2d-x的方式来将C++类注册进Lua环境详解
在cocos2d-x 2.x版本中,采用toLua++和.pkg文件的方式将自身注册到Lua环境。然而,这种方法存在明显的弊端,既需要编写实际执行功能的.pkg文件,又要编写桥接的.pkg文件和.h文件,工作量大且枯燥。因此,从cocos2d-x 3.x开始,使用bindings-generator脚本取代了toLua++。
bindings-generator脚本的工作机制
- 简化配置文件编写:无需为每个类单独编写桥接的.pkg和.h文件,只需定义一个ini文件。在该文件中,告知脚本哪些类的哪些方法需要暴露,以及注册到Lua环境中的模块名。这将原本每个类对应3个文件的工作量,缩减为所有类仅需1个.ini文件。
- 动态代码生成:深入研究了toLua++工具的生成方法,改用Python脚本动态分析C++类,自动生成桥接的.h和.cpp代码,不再调用tolua++命令。
- 底层库函数复用:虽然不再调用tolua++命令,但底层依然使用toLua++的库函数,如tolua_function。bindings-generator脚本生成的代码与使用toLua++工具生成的代码几乎相同。
bindings-generator脚本掌握了生成toLua++桥接代码的主动权,不仅节省了大量的.pkg和.h文件,还能更好地插入自定义代码,以满足cocos2d-x环境下的特殊需求,如内存回收等。因此,cocos2d-x从3.x开始放弃toLua++和.pkg,改用自行编写的bindings-generator脚本,是一种值得赞赏的明智之举。
使用bindings-generator脚本的步骤
1. 编写自定义C++类
按照cocos2d-x的规范,让自定义的C++类继承cocos2d::Ref类,以便使用cocos2d-x的内存回收机制。虽然不继承也可以,但不建议这样做,否则在Lua环境下对象的释放会比较麻烦。以下是一个示例:
// frameworks/runtime-src/Classes/MyClass.h
#include "cocos2d.h"
using namespace cocos2d;
class MyClass : public Ref
{
public:
MyClass() {};
~MyClass() {};
bool init() { return true; };
CREATE_FUNC(MyClass);
int foo(int i);
};
// frameworks/runtime-src/Classes/MyClass.cpp
#include "MyClass.h"
int MyClass::foo(int i)
{
return i + 100;
}
2. 编写.ini文件
在frameworks/cocos2d-x/tools/tolua/目录下,可以找到genbindings.py脚本和大量的.ini文件,这里是bindings-generator的实际执行环境。选择一个内容较少的.ini文件,复制一份并重新命名为MyClass.ini。大部分内容无需修改,仅需修改以下重要部分:
<a id="heading-4-frameworks-cocos2d-x-tools-tolua-MyClass-ini"></a>
# frameworks/cocos2d-x/tools/tolua/MyClass.ini
[MyClass]
prefix = MyClass
target_namespace = my
headers = %(cocosdir)s/../runtime-src/Classes/MyClass.h
classes = MyClass
此步骤是在MyClass.ini中指定MyClass.h文件的位置、要暴露的类以及注册到Lua环境的模块名。需要注意的是,如果.ini配置文件中存在macro_judgement = …宏定义,要格外小心。例如,第一次从cocos2dx_controller.ini文件复制时,若未留意macro_judgement,可能会导致生成的桥接类文件加入不该有的宏,使其仅在iOS和Android平台上生效,而在Mac平台无效。
3. 修改bindings-generator脚本
修改genbindings.py文件(约129行),将MyClass.ini文件添加进去:
<a id="heading-6-frameworks-cocos2d-x-tools-tolua-genbindings-py"></a>
# frameworks/cocos2d-x/tools/tolua/genbindings.py
cmd_args = {'cocos2dx.ini': ('cocos2d-x', 'lua_cocos2dx_auto'),
'MyClass.ini': ('MyClass', 'lua_MyClass_auto'),
...
实际上,这一步原本可以省略,只要让genbindings.py脚本自动搜索当前目录下的所有ini文件即可,期待cocos2d-x团队未来能进行这样的优化。
4. 执行bindings-generator脚本
完成上述步骤后,执行genbindings.py脚本生成桥接C++类方法:
python genbindings.py
在Mac系统上执行时,可能会遇到缺少yaml、Cheetah包的问题。安装这些Python包很简单,先执行sudo easy_install pip安装pip,然后使用pip search和sudo pip install命令进行安装。
5. 将文件加入工程
使用Xcode将自定义的C++类和生成的桥接文件添加到工程中,否则无法进行编译。
6. 修改AppDelegate.cpp
修改AppDelegate.cpp文件,执行桥接方法,将自定义的C++类注册到Lua环境中。
虽然步骤看起来较多,但实际上都比较简单。按照上述步骤操作,就能成功将自定义的C++类注册到Lua环境中。成功执行genbindings.py脚本后,会在frameworks/cocos2d-x/cocos/scripting/lua-bindings/auto/目录下看到新生成的文件。