最新文章
如何快速区分unity3d和3dmax之间的“大同小异”
03-25 16:49
Unity3D研究之自制批量修改Shader插件
03-25 16:45
Unity3D技术之为 Android 构建插件
03-25 16:43
Unity3D技术之解决ttf繁体字体不显示问题
03-25 16:41
unity下的衣服仿真
03-25 16:39
Unity3D技术之多玩家联网游戏创建说明
03-25 16:38
使用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文件。 - 动态代码生成:
bindings-generator脚本深入研究了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脚本的步骤
- 编写C++类:按照Cocos2d-x的规范,让自定义的C++类继承
cocos2d::Ref类,以便使用Cocos2d-x的内存回收机制。虽然不继承也可以,但不建议这样做,否则在Lua环境下对象的释放会比较麻烦。 - 编写
.ini文件:编写一个.ini文件,让bindings-generator根据该配置文件了解如何暴露C++类。 - 修改脚本配置:修改
bindings-generator脚本,使其读取该.ini文件。 - 生成桥接代码:执行
bindings-generator脚本,生成桥接C++类方法。 - 添加到工程:使用Xcode将自定义的C++类和生成的桥接文件添加到工程中,否则无法编译。
- 注册到Lua环境:修改
AppDelegate.cpp,执行桥接方法,将自定义的C++类注册到Lua环境。
虽然步骤较多,但实际上都很简单,下面将逐步介绍。
编写自定义C++类
习惯将文件保存到frameworks/runtime-src/Classes/目录下。
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;
}
编写.ini文件
在frameworks/cocos2d-x/tools/tolua/目录下可以找到genbindings.py脚本和大量的.ini文件,这里是bindings-generator的实际执行环境。可以选择一个内容较少的.ini文件,复制一份并重新命名为MyClass.ini。大部分内容无需修改,仅需修改以下重要部分:
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平台无效。
修改genbindings.py文件
在genbindings.py文件的129行附近,将MyClass.ini文件添加进去:
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团队能进行这样的优化。
执行脚本生成桥接文件
完成上述准备工作后,执行genbindings.py脚本:
python genbindings.py
在Mac系统上执行时,可能会遇到缺少yaml、Cheetah包的问题。安装这些Python包很简单,先执行sudo easy_install pip安装pip,然后使用pip search和sudo pip install命令进行安装。