一个使用c++在lua中创建自定义数据类型的简易方法

来源:互联网 发布:金山软件上市部分 编辑:程序博客网 时间:2024/05/07 07:50

lua是一个内嵌式的语言,很多初学者对于lua中使用c++类中的函数,或者用c++直接创建一个自己的自定义数据类型比较头疼,因为这部分确实比较乱,牵扯到内存释放分配等问题,但是如果把其中关系理清,还是很简单的,下面这段代码是一个老外写的,我做了一些修改。首先看代码。

 

  


 

 

以上是一个头文件,包含到代码中,直接就可以使用。

 

这段代码的用处是将一个c++类包装成lua中的自定义数据类型。

 

在类声明中要添加如 LUNA_CLASS_D_DEFAULT_VALS宏:

 

这个类实现了一个luaprint函数,他只会输出一个字符串。

在类声明的最后,要把这个宏加上,宏的第一个参数是类名,第二个参数是一个任意类型的指针,目前没用。

 

我们现在看看LUNA_CLASS_D_DEFAULT_VALS是什么

 

 

这个宏在类中添加了3个变量,其中m_pLink目前没用,className是一个字符串数组,用来保存类名,而Register是一个RegType类型的数组。

RegType是一个结构如下:

 struct RegType {
  const char *name;
  int(T::*mfunc)(lua_State*);
 };

这个结构保存一个c++类中的函数。他将在下面的部分进行初始化。

 

下面将要在类声明外进行刚刚那些变量的初始化工作,他们是由下面这些宏组成

 

LUNA_CLASS_D_INIT_VALS_CLASSNAME(aa,void)
LUNA_CLASS_D_INIT_VALS_FUNCNAME_START(aa)

LUNA_CLASS_D_INIT_VALS_FUNCNAME_USER(luaprint,aa)
LUNA_CLASS_D_INIT_VALS_FUNCNAME_END

 

首先LUNA_CLASS_D_INIT_VALS_CLASSNAME宏初始化m_pLink和className变量,而下面三个宏初始化RegType变量。

如果类中还有其他函数,并且他符合int(T::*mfunc)(lua_State*);的样式,那么就可以用LUNA_CLASS_D_INIT_VALS_FUNCNAME_USER添加进来。

 

那么,这个类就已经包装好,等待放到lua中。之所以说等待,是因为我们需要将这个类注册到lua中,好让lua知道,这样我们在lua中才能调用。

 

注册方法是,在程序启动的时候调用luna_register( ls, aa )宏。

其中ls是lua_state,aa是刚刚包装的类

 

至此,在lua中之需要下面这样,就可以轻松调用c函数了

 

local test = aa()

test:luaprint("123")

 

 


以上是这个luna模板最基本的应用

其他还有

LUNA_CLASS_D_INIT_VALS_FUNCNAME_ALIAS_USER用于将一个函数声明为其他名称,比如想实现lua中元表的__index函数:

LUNA_CLASS_D_INIT_VALS_FUNCNAME_ALIAS_USER(luaprint,aa,"__index")

这样,当任何对自定义函数的取值操作,都将调用luaprint函数,当然,如果不修改luaprint函数,结果肯定是错误的,__index函数必须返回一个值。

 

 

luna_register_singleton 宏用于注册一个Ogre::Singleton的派生类,一般用于lua访问c环境中全局唯一实例的类

 

BUILD_LUACLASS宏用于创建一个已经注册的类的新实例,并且放到当前堆栈中。

BUILD_LUACLASS_LP宏用于创建一个已经注册的类,其指针是c++提供,并且由c++释放。