我所理解cocos2d-x 3.6 lua -- Cocos如何绑定Lua自定义类

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

#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           = 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

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

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

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

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

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

注册类:

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

绑定函数,要注意下:

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

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

2.编译运行

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

#include "tolua++/lua_MyClass_auto.hpp"

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

register_all_MineClass(L);

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

lua代码:

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

编译运行:

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

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

时间: 2024-08-10 23:59:34

我所理解cocos2d-x 3.6 lua -- Cocos如何绑定Lua自定义类的相关文章

(转载)我所理解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.不用编写.

cocos2dx 2.x版本:简化提炼tolua++绑定自定义类到lua中使用

cocos2dx的3.x版本已经提供了更好地绑定方式,网上有很多相关的教程,这里给一个链接:http://www.cocoachina.com/bbs/read.php?tid=196416. 由于目前我们的项目使用的是2.x版本的,且已经开发了一半了,这时候不适合转3.x的版本,于是只能用2.x的老方法tolua++来实现绑定.这就有一个蛋疼的问题,太麻烦!每次都要写pkg.使用tolua++.exe解释器编译生成新的cpp,在其中添加自己的类的头文件引用,然后把这个新的cpp文件覆盖到lib

创建C++自定义类让Lua脚本调用

这里将介绍使用tolua++将自定义的C++类嵌入,让lua脚本使用 一般过程: 自定义类 -> 使用tolua++工具编译到LuaCoco2d.cpp中 -> lua调用 步骤一:自定义一个C++类,我定义一个类名为:MySprite MySprite.h MySprite.cpp 步骤二:根据自定义类创建一个.pkg文件,我们把自定义的MySprite类定义到.pkg文件中 注意:1>,只要根据自定类.h中的内容,至于.cpp的实现,binding后lua会自动调用类的函数 2>

【Quick-COCOS2D-X 3.3 如何绑定自定义类至Lua之三】动手绑定自定义类至Lua

查看[Quick-COCOS2D-X 3.3 如何绑定自定义类至Lua之二]新建项目中配制环境,我们完美的在新建项目中完成了绑定需要的环境,接下来才是最关健的一步.绑定自定义C++类至Lua. 事实上引擎为了方便我们应对不同平台,已经帮我们创建了不同平台的工程项目.为了编辑代码方便,我使用VS2013打开了"runtime-src"文件夹下的"proj.win32"工程. 前往项目录径"F:\Cocos2dx-Lua\Garfield\frameworks

Lua - 决定开始分析Lua的源代码

lmathlib.c, lstrlib.c: get familiar with the external C API. Don't bother with the pattern matcher though. Just the easy functions. lapi.c: Check how the API is implemented internally. Only skim this to get a feeling for the code. Cross-reference to

cocos2dx lua 绑定之二:手动绑定自定义类中的函数

cococs2dx 3.13.1 + vs2013 + win10 1.首先按照<cocos2dx lua 绑定之一:自动绑定自定义类>绑定Student类 2.在Student类中增加一个用于测试手动绑定的函数manual_call ①Student.h中增加函数 //手动绑定调用函数 void manual_call(); ②Student.cpp中增加函数实现 //和自动绑定相比,只增加了这个函数 void Student::manual_call() { std::cout <&

在C++使用LUA交互,LUA实现闭包,C++/LUA相互闭包

LUA可谓是配置文件神器,具体功能用过才知道,接近两年没用了抽了俩小时熟悉了下基本的用法. 包括C/LUA堆栈操作 函数相互调用 以及LUA的闭包 C++和LUA相互闭包 想要灵活使用LUA必须先要学习 LUA和C的堆栈交互模型 类似于汇编函数调用方式了 很有意思. 要学习LUA首先要理解LUA和C/C++交互的堆栈lua_State  这里引用网友的一篇文章很详细 http://wind-catalpa.blog.163.com/blog/static/11475354320131191031

cocos2dx-3.x 导出自定义类到 lua 过程

一.简介 最近正在学习cocos2d中的lua游戏开发,因为lua开发的热更新特性,大家开发游戏好像都会优先选择lua作为开发语言. 但是遇到一个问题,用lua写一些简单的程序没什么问题,但是一旦需要一个复杂的类,在lua中直接写就感觉有些吃力.所以想到,可以把游戏开发中比较复杂的模块使用c++完成,然后导出到lua,让lua可以轻松调用. 我从头到尾完整地完成了cocos2dx-3.x中自定义类的导出过程,在网上查了好多资料,也碰到了很多错误,然而网上关于这块的文章比较零散,如果有初学者使用的

cocos2d-x 3.0 在lua中调用自定义类

环境 windows8, cocos2d-x 3.0, 现在开始安装需要的一些其它包 1. 按README.mdown文档上面要求的, 下载在windows下要安装的东东, 主要就是python2.7.3, PyYAML-3.10.win32-py2.7, pyCheetah 这些东东在README.mdown上面都给好了连接, 直接下载就行了, 安装好python后, 在系统环境变量的PATH中设置python所在的目录2. 安装android-ndk-r9b, 下载地址:http://dl.