cocos2d-x 2.x 与 cocos2d-x 3.x 差异(tolua++) cocos2d-x在2.x 版本里就是用 toLua++和.pkg文件 这么把自己注册进Lua环境里的,然而从 cocos2d-x 3.x 开始,用 bindings-generator 脚本代替了toLua++。 bindings-gen
cocos2d-x 2.x 与 cocos2d-x 3.x 差异(tolua++)
cocos2d-x在2.x版本里就是用toLua++和.pkg文件这么把自己注册进Lua环境里的,然而从cocos2d-x 3.x开始,用bindings-generator脚本代替了toLua++。
1、不用编写.pkg和.h文件了,直接定义一个 ini 文件, 注册到Lua环境 里的模块名是什么,就行了。
2、摸清了toLua++工具的生成方法,改由Python脚本动态分析C++类,自动生成桥接的.h和.cpp代码,不调用tolua++命令了
3、虽然不再调用tolua++命令了,但是底层仍然使用toLua++的库函数,比如tolua_function,bindings-generator脚本生成的代码就跟使用toLua++工具生成的几乎一样
接下来说怎么用bindings-generator脚本:
1、写自己的C++类,按照cocos2d-x的规矩,继承cocos2d::Ref类,以便使用cocos2d-x的内存回收机制。
2、编写一个.ini文件,让bindings-generator可以根据这个配置文件知道C++类该怎么暴露出来
3、修改bindings-generator脚本,让它去读取这个.ini文件
4、执行bindings-generator脚本,生成桥接C++类方法
5、用VS2012将自定义的C++类和生成的桥接文件加入工程,不然编译不到
6、修改AppDelegate.cpp,执行桥接方法,自定义的C++类就注册进Lua环境里了。
首先是自定义的C++类。我习惯将文件保存在 frameworks/runtime-src/Classes/ 目录下:
frameworks/runtime-src/Classes/MyClass.h
[cpp] view plain copy
- #include "cocos2d.h"
- using namespace cocos2d;
- class MyClass : public Ref
- {
- public:
- MyClass() {};
- ~MyClass() {};
- bool init() { return true; };
- CREATE_FUNC(MyClass);
- int foo(int i);
- };
[cpp] view plain copy
- #include "MyClass.h"
- int MyClass::foo(int i)
- {
- return i + 100;
- }
frameworks/cocos2d-x/tools/tolua/MyClass.ini
[cpp] view plain copy
- [MyClass]
- prefix = MineClass # 添中前缀名XX,注册文件头及注册函数名以前缀名(XX)组合命名
- target_namespace = my # 空间命名,调用时,以my.xxx, xxx为自定义类的方法
- headers = %(cocosdir)s/../runtime-src/Classes/MyClass.h # 获取自定义类的文件头
- classes = MyClass # 需要注册类YY(方法),同时注册函数名以前缀名(XX)_YY组合命名
[cpp] view plain copy
- cmd_args = {'cocos2dx.ini' : ('cocos2d-x', 'lua_cocos2dx_auto'), \
- 'MyClass.ini' : ('MyClass', 'lua_MyClass_auto'), \
- ...
至此,生成桥接文件的准备工作就做好了,执行genbindings.py脚本:
[cpp] view plain copy
- python genbindings.py
注:若Python报错,看下是否缺少yaml、Cheetah包,若是,安装包就行了。
简单解释下编译成后lua_MyClass_auto.cpp
[cpp] view plain copy
- TOLUA_API int register_all_MineClass(lua_State* tolua_S)
- {
- //入口点,它创建管理的内部变量
- tolua_open(tolua_S);
- //创建新模块
- tolua_module(tolua_S,"my",0);
- //注册一个模块或类
- tolua_beginmodule(tolua_S,"my");
- // 类的注册
- lua_register_MineClass_MyClass(tolua_S);
- tolua_endmodule(tolua_S);
- return 1;
- }
[cpp] view plain copy
- int lua_register_MineClass_MyClass(lua_State* tolua_S)
- {
- tolua_usertype(tolua_S,"MyClass"); //注册用户类型
- tolua_cclass(tolua_S,"MyClass","MyClass","cc.Ref",nullptr); //注册类
- tolua_beginmodule(tolua_S,"MyClass"); //注册模块
- tolua_function(tolua_S,"new",lua_MineClass_MyClass_constructor); //绑定函数(将Lua里面MyClass对象的”new”绑定到你的lua_MineClass_MyClass_constructor()函数中去.)
- tolua_function(tolua_S,"init",lua_MineClass_MyClass_init);
- tolua_function(tolua_S,"foo",lua_MineClass_MyClass_foo);
- tolua_function(tolua_S,"create", lua_MineClass_MyClass_create);
- tolua_endmodule(tolua_S);
- std::string typeName = typeid(MyClass).name(); //保存注册类
- g_luaType[typeName] = "MyClass";
- g_typeCast["MyClass"] = "MyClass";
- return 1;
- }
[cpp] view plain copy
- cobj = (MyClass*)tolua_tousertype(tolua_S,1,0); //是将数据栈下的对象以(CTest* )的指针形式弹出来。
2.编译运行
打开Classes/lua_module_register.h文件,添加头文件
- #include "tolua++/lua_MyClass_auto.hpp"
[cpp] view plain copy
- register_all_MineClass(L);
lua代码:
[cpp] view plain copy
- function myadd(x, y)
- -- 自定义
- local test = my.MyClass:create()
- print("lua bind: " .. test:foo(99))
- return x + y
- end
----------------------------------------------------------------------------------------------------------------------------- 本文转自:http://blog.csdn.net/rexuefengye/article/details/46553239