同一用户数据的Lua数组和面向对象的访问

时间:2017-10-22 04:19:05

标签: c++ lua

我有一个用C ++编写的CArray类,并以Lua作为Array公开。

1)创建新的用户数据:

int Array_new(lua_State* L)
{
    int len = luaL_checkint(L, 1);
    CArray<std::string> **Arr = (CArray<std::string>**)lua_newuserdata(L, sizeof(CArray<std::string>*));
    *Arr = new CArray<std::string>(len);
    luaL_getmetatable(L, "ArrayMetatable");
    lua_setmetatable(L, -2);

    return 1;
}

2)访问元素:

int Array_getValue(lua_State* L)
{
    CArray<std::string>* arr = *(CArray<std::string>**)lua_touserdata(L, 1);
    int pos=luaL_checknumber(L, 2)-1;

    //Omitted for brevity
    lua_pushstring(L, stdStr.c_str());

    return 1;
}

3)注册Lua:

int luaopen_Array(lua_State* L)
{
    luaL_newmetatable(L, "ArrayMetatable"); // metatable1

    luaL_setfuncs(L, Array_metatable, 0);
    lua_pushstring(L, "__index");
    lua_pushvalue(L, -2);  //  metatable1 __index metatable1
    lua_settable(L, -3); // metatable1[__index]=metatable1

    /*luaL_newmetatable(L, "ArrayMetatable_2"); //  metatable1 metatable2
    lua_pushstring(L, "__index"); //  metatable1 metatable2 __index
    lua_pushstring(L, "get"); //  metatable1 metatable2 __index get
    lua_gettable(L, 1);  //  metatable1 metatable2 __index
    lua_settable(L, 2);  

    lua_pushvalue(L, 1); //metatable1 metatable2 metatable1*/

    lua_setglobal(L, "Array");

    return 0;
}

问题是我不得不选择Lua代码来访问数组中的元素: a) arr:get(1)以获取第一个元素 b) arr[1]获取第一个元素。

然而 a b 不能同时发挥作用,所以要么我更喜欢样式样式b 即可。是否可以通过修改第3步同时执行 a b

到目前为止,我提交的代码在第2步时出现错误,如果我尝试使用arr[2]等Lua表达式,使变量arr的地址为0xcccccc。

2 个答案:

答案 0 :(得分:0)

您可以添加__index方法和get方法,只需单独添加即可。

答案 1 :(得分:0)

注册功能看起来有些混乱。

通常你会有两个元表 - 全局函数和成员函数。

static const struct luaL_Reg Array_globals[] = {
    { "new", Array_new },
    { NULL,NULL }
};

static const struct luaL_Reg Array_members[] = {
    { "get", Array_getValue},
    { "__index", Array_getValue },
    { NULL,NULL }
};

luaopen_函数只需要使用适当的方法构建表。 我还建议您撰写__len__setindex

int luaopen_Array(lua_State* L)
{
    luaL_newmetatable(L, "ArrayMetatable"); // metatable1

    luaL_setfuncs(L, Array_members, 0);

    luaL_newlib( L, Array_globals );
    return 1; // return table to caller.
}