Cocos如何绑定Lua自定义类

cocos2d-x在2.x版本里就是用toLua++和.pkg文件这么把自己注册进Lua环境里的,然而从cocos2d-x 3.x开始,用bindings-generator脚本代替了toLua++。


    bindings-generator脚本的工作机制是:
         1、不用编写.pkg和.h文件了,直接定义一个 ini文件, 注册到Lua环境里的模块名是什么,就行了。
         2、摸清了toLua++工具的生成方法,改由Python脚本动态分析C++类,自动生成桥接的.h和.cpp代码,不调用tolua++命令了

        3、虽然不再调用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的规矩,继承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
  1. #include "cocos2d.h"  
  2.   
  3. using namespace cocos2d;  
  4.   
  5. class MyClass : public Ref  
  6. {  
  7. public:  
  8.   MyClass()   {};  
  9.   ~MyClass()  {};  
  10.   bool init() { return true; };  
  11.   CREATE_FUNC(MyClass);  
  12.   
  13.   int foo(int i);  
  14. };  
    frameworks/runtime-src/Classes/MyClass.cpp

[cpp]  view plain  copy
  1. #include "MyClass.h"  
  2.   
  3. int MyClass::foo(int i)  
  4. {  
  5.   return i + 100;  
  6. }  
    然后编写.ini文件。在frameworks/cocos2d-x/tools/tolua/目录下能看到genbindings.py脚本和一大堆.ini文件,这些就是bindings-generator的实际执行环境了。随便找一个内容比较少的.ini文件,复制一份,重新命名为MyClass.ini。大部分内容都可以凑合不需要改,这里仅列出必须要改的重要部分:
    frameworks/cocos2d-x/tools/tolua/MyClass.ini

[cpp]  view plain  copy
  1. [MyClass]  
  2. prefix           = MineClass                                            # 添中前缀名XX,注册文件头及注册函数名以前缀名(XX)组合命名  
  3. target_namespace = my                                               # 空间命名,调用时,以my.xxx, xxx为自定义类的方法  
  4. headers          = %(cocosdir)s/../runtime-src/Classes/MyClass.h    # 获取自定义类的文件头  
  5. classes          = MyClass                                          # 需要注册类YY(方法),同时注册函数名以前缀名(XX)_YY组合命名  
    frameworks/cocos2d-x/tools/tolua/genbindings.py
[cpp]  view plain  copy
  1. cmd_args = {'cocos2dx.ini' : ('cocos2d-x''lua_cocos2dx_auto'), \  
  2.             'MyClass.ini' : ('MyClass''lua_MyClass_auto'), \  
  3.             ...  
    (其实这一步本来是可以省略的,只要让genbindings.py脚本自动搜寻当前目录下的所有ini文件就行了,不知道将来cocos2d-x团队会不会这样优化)
至此,生成桥接文件的准备工作就做好了,执行genbindings.py脚本:

[cpp]  view plain  copy
  1. python genbindings.py  
    成功执行genbindings.py脚本后,会在frameworks/cocos2d-x/cocos/scripting/lua-bindings/auto/目录下看到新生成的文件:


        


    注:若python报错,看下是否缺少yaml、Cheetah包,若是,安装包就行了。

    简单解释下编译成后lua_MyClass_auto.cpp

[cpp]  view plain  copy
  1. TOLUA_API int register_all_MineClass(lua_State* tolua_S)  
  2. {  
  3.     //入口点,它创建管理的内部变量  
  4.     tolua_open(tolua_S);  
  5.     //创建新模块  
  6.     tolua_module(tolua_S,"my",0);  
  7.     //注册一个模块或类  
  8.     tolua_beginmodule(tolua_S,"my");  
  9.     // 类的注册  
  10.     lua_register_MineClass_MyClass(tolua_S);  
  11.   
  12.     tolua_endmodule(tolua_S);  
  13.     return 1;  
  14. }  
    注册类:

[cpp]  view plain  copy
  1. int lua_register_MineClass_MyClass(lua_State* tolua_S)  
  2. {  
  3.     tolua_usertype(tolua_S,"MyClass");                                   //注册用户类型  
  4.     tolua_cclass(tolua_S,"MyClass","MyClass","cc.Ref",nullptr);          //注册类  
  5.   
  6.     tolua_beginmodule(tolua_S,"MyClass");                                //注册模块  
  7.         tolua_function(tolua_S,"new",lua_MineClass_MyClass_constructor); //绑定函数(将Lua里面MyClass对象的”new”绑定到你的lua_MineClass_MyClass_constructor()函数中去.)  
  8.         tolua_function(tolua_S,"init",lua_MineClass_MyClass_init);  
  9.         tolua_function(tolua_S,"foo",lua_MineClass_MyClass_foo);  
  10.         tolua_function(tolua_S,"create", lua_MineClass_MyClass_create);  
  11.     tolua_endmodule(tolua_S);  
  12.     std::string typeName = typeid(MyClass).name();                      //保存注册类  
  13.     g_luaType[typeName] = "MyClass";  
  14.     g_typeCast["MyClass"] = "MyClass";  
  15.     return 1;  
  16. }  
    绑定函数,要注意下:

[cpp]  view plain  copy
  1. cobj = (MyClass*)tolua_tousertype(tolua_S,1,0); //是将数据栈下的对象以(CTest* )的指针形式弹出来。  
    从栈中弹出对象(其实是自定类的对象),接着把对象引用方法(包括含参数及handle)返回结果压栈,实现c、lua之间互相调用了。


2.编译运行 

    打开Classes/lua_module_register.h文件,添加头文件 

[cpp]  view plain  copy
  1. #include "tolua++/lua_MyClass_auto.hpp"  
    在static int lua_module_register(lua_State* L)添加注册函数

[cpp]  view plain  copy
  1. register_all_MineClass(L);  
    若vs2012编译错误,估计都是没把源文件及生成的文件加入工程; 若有特殊处理,比如更换genbindings.py脚本生成文件路径,注意在vs2012环境->属性->c/c++->附加包含目录,添加路径。

lua代码:

[cpp]  view plain  copy
  1. function myadd(x, y)  
  2.     -- 自定义  
  3.     local test = my.MyClass:create()  
  4.     print("lua bind: " .. test:foo(99))  
  5.     return x + y  
  6. end  
编译运行:



引用博客:http://segmentfault.com/a/1190000000631630

引用文章:http://cn.cocos2d-x.org/tutorial/show?id=2496

转载地址: http://blog.csdn.net/my183100521/article/details/46553239
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值