您的位置:首页 > 编程语言 > Lua

LUA与c++交互5.3

2020-03-05 09:16 861 查看

网上基本都是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;
}
  • 点赞
  • 收藏
  • 分享
  • 文章举报
Sprinkble 发布了15 篇原创文章 · 获赞 0 · 访问量 471 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: