(转载)我所理解Cocos2d-x 3.6(Lua):Cocos如何绑定Lua自定义类

我所理解Cocos2d-x 3.6(Lua):Cocos如何绑定Lua自定义类

热血枫叶2015-06-19 16:27:182289 次阅读

Cocos2d-x 2.x 与 Cocos2d-x 3.x 差异(tolua++)

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

1234567891011 `#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

12345 `#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

12345 `[MyClass]``prefix = MineClass # 添中前缀名XX,注册文件头及注册函数名以前缀名(XX)组合命名``target_namespace = my # 空间命名,调用时,以my.xxx, xxx为自定义类的方法``headers = %(cocosdir)s/../runtime-src/Classes/MyClass.h # 获取自定义类的文件头``classes = MyClass # 需要注册类YY(方法),同时注册函数名以前缀名(XX)_YY组合命名`

frameworks/cocos2d-x/tools/tolua/genbindings.py

12 `cmd_args = {``'cocos2dx.ini'` `: (``'cocos2d-x'``,``'lua_cocos2dx_auto'``),``'MyClass.ini'` `: (``'MyClass'``,``'lua_MyClass_auto'``),`

(其实这一步本来是可以省略的,只要让genbindings.py脚本自动搜寻当前目录下的所有ini文件就行了,不知道将来Cocos2d-x团队会不会这样优化)

至此,生成桥接文件的准备工作就做好了,执行genbindings.py脚本:

1 `python genbindings.py`

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

20150618223225231.png

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

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

12345678910111213 `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;``}`

注册类:

123456789101112131415 `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;``}`

绑定函数,要注意下:

1 `cobj = (MyClass*)tolua_tousertype(tolua_S,1,0);``//是将数据栈下的对象以(CTest* )的指针形式弹出来。`

从栈中弹出对象(其实是自定类的对象),接着把对象引用方法(包括含参数及handle)返回结果压栈,实现c、lua之间互相调用了。

2.编译运行

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

1 `#include "tolua++/lua_MyClass_auto.hpp"`

在static int lua_module_register(lua_State* L)添加注册函数

1 `register_all_MineClass(L);`

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

lua代码:

123456 `function myadd(x, y)``-- 自定义``local test = my.MyClass:create()``print(``"lua bind: "` `.. test:foo(99))``return` `x + y``end`

编译运行:

20150618225020032.jpg

参考文章:

【教程分享】Cocos如何绑定Lua自定义类

Cocos2d-x下Lua调用自定义C++类和函数的最佳实践

来源网址:http://blog.csdn.net/rexuefengye/article/details/46553239
原文链接: https://www.cnblogs.com/wodehao0808/p/4737334.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/220770

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月13日 上午11:01
下一篇 2023年2月13日 上午11:01

相关推荐