在c++中,允许我们创建类而lua并不是c++写出,我们如何把类注册到c++中去呢?需要一些通用的技巧,包括两个方面的东西,先把创建类的方法注册到全局函数中,在元表中注册各个成员函数。
创建一个CTest的类。
test.h
#ifndef __TEST_H__
#define __TEST_H__
class CTest
{
public:
CTest();
~CTest();
int getA();
void setA(int a);
private:
int m_a;
};
#endif
test.cpp
#include "test.h"
CTest::CTest()
{
m_a = 0;
}
CTest::~CTest()
{
}
int CTest::getA()
{
return m_a;
}
void CTest::setA(int a)
{
m_a = a;
}
CTest
中有两个方法,一个是getA
,另外一个是setA
。
source.cpp
#include "test.h"
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include "luaconf.h"
};
static int CreateTest(lua_State* L)
{
CTest** ppTest = (CTest**)lua_newuserdata(L, sizeof(CTest*));
*ppTest = new CTest;
luaL_getmetatable(L, "test");
lua_setmetatable(L, -2);
return 1;
}
static int TestGetA(lua_State* L)
{
CTest** ppTest = (CTest**)luaL_checkudata(L, 1, "test");
luaL_argcheck(L, ppTest != NULL, 1, "invalid user data");
lua_pushnumber(L, (int)(*ppTest)->getA());
return 1;
}
static int TestSetA(lua_State* L)
{
CTest** ppTest = (CTest**)luaL_checkudata(L, 1, "test");
luaL_argcheck(L, ppTest != NULL, 1, "invalid user data");
int a = (int)lua_tointeger(L, 2);
(*ppTest)->setA(a);
return 0;
}
static int DeleteTest(lua_State* L)
{
CTest** ppTest = (CTest**)luaL_checkudata(L, 1, "test");
delete *ppTest;
printf("test is deleted");
return 0;
}
static const struct luaL_Reg test_reg_f[] =
{
{ "test", CreateTest },
{ NULL, NULL },
};
static const struct luaL_Reg test_reg_mf[] =
{
{ "TestGetA", TestGetA },
{ "TestSetA", TestSetA },
{ "__gc", DeleteTest },
{ NULL, NULL },
};
static int testModelOpen(lua_State* L)
{
luaL_newlib(L, test_reg_f);
return 1;
}
int main()
{
int top = 0;
lua_State* L = luaL_newstate();
top = lua_gettop(L);
luaopen_base(L);
luaL_openlibs(L);
top = lua_gettop(L);
//加载模块
luaL_requiref(L, "testModel", testModelOpen, 0);
top = lua_gettop(L);
//创建metatable
luaL_newmetatable(L, "test");
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
luaL_setfuncs(L, test_reg_mf, 0);
lua_pop(L, 1);
top = lua_gettop(L);
int ret = luaL_dofile(L, "test.lua");
if (ret != 0)
{
printf("%s", lua_tostring(L, -1));
}
lua_close(L);
getchar();
return 1;
}
定义了 CreateTest
,主要是采用lua_newuserdata
把创建的CTest放在自定义的数据块中,并放在元表test
下。
而对元表test
进行相应的处理。
分别处理两个函数TestGetA
和TestSetA
,这两个函数分别处理的是成员函数,一个是getA
,另外一个是setA
。
这里用到了元表中的几个元素,其中
{ "__gc", DeleteTest },
指的是垃圾回收,也就是调用完以后最后会调用__gc
lua_setfield(L, -2, "__index");
__index
指的是在查找某一个元素无法找到时,该用哪个进行替换。