Cocos2d-x手动绑定C++类到Lua
作者:glory 首发泰然,转发请注明出处。
Cocos2d-x 3.0开始,Lua Binding使用tolua++方式自动绑定底层C++类到Lua层,使用户能够用Lua方式调用引擎各种接口。但是用户还是希望手动绑定某些自定义类,所以接下来的内容将一步一步讲解如何手动将自定义C++类绑定到Lua。
创建自定义类
首先,定义一个类Foo,这个类就是接下来要绑定到Lua的类。
注意:所有C++类文件必须放在 Classes 文件夹里,所有Lua文件必须放在 Resources 文件夹里。
#include@H_301_8@ @H_301_8@<iostream>@H_301_8@
@H_301_8@#include@H_301_8@ @H_301_8@<sstream>@H_301_8@
@H_301_8@class@H_301_8@ @H_301_8@Foo@H_301_8@
@H_301_8@{@H_301_8@
@H_301_8@public@H_301_8@:@H_301_8@
@H_301_8@Foo@H_301_8@(@H_301_8@const@H_301_8@ std@H_301_8@::@H_301_8@string@H_301_8@ @H_301_8@&@H_301_8@ name@H_301_8@)@H_301_8@ @H_301_8@:@H_301_8@ name@H_301_8@(@H_301_8@name@H_301_8@)@H_301_8@
@H_301_8@{@H_301_8@
std@H_301_8@::@H_301_8@cout @H_301_8@<<@H_301_8@ @H_301_8@"Foo is born"@H_301_8@ @H_301_8@<<@H_301_8@ std@H_301_8@::@H_301_8@endl@H_301_8@;@H_301_8@
@H_301_8@}@H_301_8@
std@H_301_8@::@H_301_8@string@H_301_8@ @H_301_8@Add@H_301_8@(@H_301_8@int@H_301_8@ a@H_301_8@,@H_301_8@ @H_301_8@int@H_301_8@ b@H_301_8@)@H_301_8@
@H_301_8@{@H_301_8@
std@H_301_8@::@H_301_8@stringstream ss@H_301_8@;@H_301_8@
ss @H_301_8@<<@H_301_8@ name @H_301_8@<<@H_301_8@ @H_301_8@": "@H_301_8@ @H_301_8@<<@H_301_8@ a @H_301_8@<<@H_301_8@ @H_301_8@" + "@H_301_8@ @H_301_8@<<@H_301_8@ b @H_301_8@<<@H_301_8@ @H_301_8@" = "@H_301_8@ @H_301_8@<<@H_301_8@ @H_301_8@(@H_301_8@a@H_301_8@+@H_301_8@b@H_301_8@);@H_301_8@
@H_301_8@return@H_301_8@ ss@H_301_8@.@H_301_8@str@H_301_8@();@H_301_8@
@H_301_8@}@H_301_8@
@H_301_8@~@H_301_8@Foo@H_301_8@()@H_301_8@
@H_301_8@{@H_301_8@
std@H_301_8@::@H_301_8@cout @H_301_8@<<@H_301_8@ @H_301_8@"Foo is gone"@H_301_8@ @H_301_8@<<@H_301_8@ std@H_301_8@::@H_301_8@endl@H_301_8@;@H_301_8@
@H_301_8@}@H_301_8@
@H_301_8@private@H_301_8@:@H_301_8@
std@H_301_8@::@H_301_8@string@H_301_8@ name@H_301_8@;@H_301_8@
@H_301_8@};@H_301_8@
这个类有三个函数,构造函数、Add函数和析构函数。作用是输出不同字符串,以判断各函数是否被调用。
绑定自定义类到Lua
开始前,先了解下绑定C++类的一些基本原理。
首先创建一个userdata来存放C++类对象指针,然后给userdata添加元表,用index元方法映射C++类中的对象方法。
userdata
Lua中userdata为自定义类型,即用户自定义C++类类型,非Lua基本类型。绑定过程中用来存放C++类对象指针,从而将C++类映射到Lua中。
元表(Metatable)
带有索引的集合的表,绑定过程中用来存放和映射C++类中的对象和对象方法。
__index
元表索引,指向用来存放userdata的元表。用来索引已创建的元表栈中的C++类名以及类方法名。
#include@H_301_8@ @H_301_8@"fun.h"@H_301_8@
@H_301_8@extern@H_301_8@ @H_301_8@"C"@H_301_8@
@H_301_8@{@H_301_8@
@H_301_8@#include@H_301_8@ @H_301_8@<lua.h>@H_301_8@
@H_301_8@#include@H_301_8@ @H_301_8@<lauxlib.h>@H_301_8@
@H_301_8@#include@H_301_8@ @H_301_8@<lualib.h>@H_301_8@
@H_301_8@}@H_301_8@
@H_301_8@// 1.@H_301_8@
@H_301_8@int@H_301_8@ l_Foo_constructor@H_301_8@(@H_301_8@lua_State @H_301_8@*@H_301_8@ l@H_301_8@)@H_301_8@
@H_301_8@{@H_301_8@
@H_301_8@const@H_301_8@ @H_301_8@char@H_301_8@ @H_301_8@*@H_301_8@ name @H_301_8@=@H_301_8@ luaL_checkstring@H_301_8@(@H_301_8@l@H_301_8@,@H_301_8@ @H_301_8@1@H_301_8@);@H_301_8@
@H_301_8@Foo@H_301_8@ @H_301_8@**@H_301_8@ udata @H_301_8@=@H_301_8@ @H_301_8@(@H_301_8@Foo@H_301_8@ @H_301_8@**)@H_301_8@lua_newuserdata@H_301_8@(@H_301_8@l@H_301_8@,@H_301_8@ @H_301_8@sizeof@H_301_8@(@H_301_8@Foo@H_301_8@ @H_301_8@*));@H_301_8@
@H_301_8@*@H_301_8@udata @H_301_8@=@H_301_8@ @H_301_8@new@H_301_8@ @H_301_8@Foo@H_301_8@(@H_301_8@name@H_301_8@);@H_301_8@
@H_301_8@return@H_301_8@ @H_301_8@1@H_301_8@;@H_301_8@
@H_301_8@}@H_301_8@
@H_301_8@// 2.@H_301_8@
@H_301_8@Foo@H_301_8@ @H_301_8@*@H_301_8@ l_CheckFoo@H_301_8@(@H_301_8@lua_State @H_301_8@*@H_301_8@ l@H_301_8@,@H_301_8@ @H_301_8@int@H_301_8@ n@H_301_8@)@H_301_8@
@H_301_8@{@H_301_8@
@H_301_8@return@H_301_8@ @H_301_8@*(@H_301_8@Foo@H_301_8@ @H_301_8@**)@H_301_8@luaL_checkudata@H_301_8@(@H_301_8@l@H_301_8@,@H_301_8@ n@H_301_8@,@H_301_8@ @H_301_8@"luaL_Foo"@H_301_8@);@H_301_8@
@H_301_8@}@H_301_8@
@H_301_8@// 3.@H_301_8@
@H_301_8@int@H_301_8@ l_Foo_add@H_301_8@(@H_301_8@lua_State @H_301_8@*@H_301_8@ l@H_301_8@)@H_301_8@
@H_301_8@{@H_301_8@
@H_301_8@Foo@H_301_8@ @H_301_8@*@H_301_8@ foo @H_301_8@=@H_301_8@ l_CheckFoo@H_301_8@(@H_301_8@l@H_301_8@,@H_301_8@ @H_301_8@1@H_301_8@);@H_301_8@
@H_301_8@int@H_301_8@ a @H_301_8@=@H_301_8@ luaL_checknumber@H_301_8@(@H_301_8@l@H_301_8@,@H_301_8@ @H_301_8@2@H_301_8@);@H_301_8@
@H_301_8@int@H_301_8@ b @H_301_8@=@H_301_8@ luaL_checknumber@H_301_8@(@H_301_8@l@H_301_8@,@H_301_8@ @H_301_8@3@H_301_8@);@H_301_8@
std@H_301_8@::@H_301_8@string@H_301_8@ s @H_301_8@=@H_301_8@ foo@H_301_8@->@H_301_8@Add@H_301_8@(@H_301_8@a@H_301_8@,@H_301_8@ b@H_301_8@);@H_301_8@
lua_pushstring@H_301_8@(@H_301_8@l@H_301_8@,@H_301_8@ s@H_301_8@.@H_301_8@c_str@H_301_8@());@H_301_8@
@H_301_8@return@H_301_8@ @H_301_8@1@H_301_8@;@H_301_8@
@H_301_8@}@H_301_8@
@H_301_8@// 4.@H_301_8@
@H_301_8@int@H_301_8@ l_Foo_destructor@H_301_8@(@H_301_8@lua_State @H_301_8@*@H_301_8@ l@H_301_8@)@H_301_8@
@H_301_8@{@H_301_8@
@H_301_8@Foo@H_301_8@ @H_301_8@*@H_301_8@ foo @H_301_8@=@H_301_8@ l_CheckFoo@H_301_8@(@H_301_8@l@H_301_8@,@H_301_8@ @H_301_8@1@H_301_8@);@H_301_8@
@H_301_8@delete@H_301_8@ foo@H_301_8@;@H_301_8@
@H_301_8@return@H_301_8@ @H_301_8@0@H_301_8@;@H_301_8@
@H_301_8@}@H_301_8@
@H_301_8@// 5.@H_301_8@
@H_301_8@void@H_301_8@ @H_301_8@RegisterFoo@H_301_8@(@H_301_8@lua_State @H_301_8@*@H_301_8@ l@H_