LUA与c++交互5.3

网上基本都是5.1的自己结合看书找资料写了个5.3的顺利运行

#include"lua.hpp"

#pragma comment(lib,"luaLib.lib")

#include"lua.hpp"

static char meta[] = "array_meta";
typedef struct Tag_Array
{
	int    size;
	double value[1];
}Array;

//检查第一个参数 userdata的类型是不是相同的
//(有很多类型的userdata,比如别人写的库也是userdata)
//用元表来判断,所以key值要选择不会冲突的							
#define checkLegalArray(L) \
				(Array*)luaL_checkudata(L, 1, meta)
//lua a = array.new(size)
static int array_new(lua_State *L) {
	//arg size
	int n = luaL_checknumber(L, 1);
	luaL_argcheck(L, n >= 1, 1, "size need greater than 1");
	//allocate size
	int actual_size = sizeof(Array) + sizeof(double)*(n - 1);
	Array *a = (Array*)(lua_newuserdata(L, actual_size));//将userdata压栈
	a->size = n;

	//为所有新建的数组设置元表(标识符)
	luaL_setmetatable(L, meta);
	
	return 1;
}
//lua a.size(a)
static int array_size(lua_State *L) {
	//检查第一个参数 userdata的类型是不是一致的
	Array *a = checkLegalArray(L);
	luaL_argcheck(L, a != nullptr, 1, "invalid array arg!");
	lua_pushnumber(L, a->size);
	return 1;
}
//lua a.set(a,idx,val)
static int array_set(lua_State *L) {
	//检查第一个参数 userdata的类型是不是一致的
	Array *a = checkLegalArray(L);
	luaL_argcheck(L, a != nullptr, 1, "invalid array arg!");
	
	int idx = lua_tonumber(L, 2);
	luaL_argcheck(L, 1 <= idx&& idx <= a->size, 2, "index out of range");
	
	luaL_checkinteger(L, 3);
	int val = lua_tonumber(L, 3);
	
	a->value[idx-1] = val;
	return 0;
}
//lua a.get(L,idx)
static int array_get(lua_State *L) {
	//检查第一个参数 userdata的类型是不是相同的
	Array *a = checkLegalArray(L);
	luaL_argcheck(L, a != nullptr, 1, "invalid array arg!");

	int idx = lua_tonumber(L, 2);
	luaL_argcheck(L, 1 <= idx&& idx <= a->size, 2, "index out of range");

	lua_pushnumber(L, a->value[idx - 1]);
	return 1;
}
//数组的操作集合
static const luaL_Reg opr_array[]{
	{ "get" ,array_get  },
	{ "size",array_size },
	{ "set" ,array_set  },
	{ NULL  ,NULL }
};
//函数库操作集合
static const luaL_Reg opr_lib[]{
	{ "new" ,array_new },
	{ NULL  ,NULL }
};
extern "C" __declspec(dllexport) int luaopen_array(lua_State *L)
{
	printf("call luaopen_array\n");
	//创建元表,设置index
	luaL_newmetatable(L, meta);//注册,将table 压入栈中
	lua_pushstring(L, "__index");//key
	//复制一次metatable
	lua_pushvalue(L, -2);//val
	//将元表设置为自己本身(这样可以支持a:size() or a.size(a),而不是array.size(a))
	lua_settable(L, -3); //metatable.__index = metatable
	loadAllLib(L, opr_array,true);//将所有除New外的函数放入metatable

	
	//注意我们返回的是一个表,该表的key只有new (调用形式是array=require("array"))
	//所以我们new一个对象,该对象的访问会触发__index
	//注意我们会在new()函数里将userdata的元表设置
	//为上面的元表,所以a.size就会调用meta.size
	//为什么不这样设置就不能a.size(a) or a:size()
	//因为new返回的userdata里没有任何的key,所以设置完就可以了
	loadAllLib(L, opr_lib);
	return 1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值