lua入门教程:第十章 C API 类方式注册

在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进行相应的处理。

分别处理两个函数TestGetATestSetA,这两个函数分别处理的是成员函数,一个是getA,另外一个是setA

这里用到了元表中的几个元素,其中

{ "__gc", DeleteTest },

指的是垃圾回收,也就是调用完以后最后会调用__gc

lua_setfield(L, -2, "__index");

__index 指的是在查找某一个元素无法找到时,该用哪个进行替换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

go2coding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值