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

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

问题描述:

我有一个使用C++编写的CArray类,它暴露给Lua为Array。相同用户数据的Lua数组和面向对象访问

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]获取第一个元素。

然而一个b不同时工作,所以无论是我喜欢风格B型。是否可以通过修改第3步同时执行ab

到目前为止我提供的代码在步骤2给出了一个错误,如果我尝试一个Lua表达如arr[2]使得可变arr的地址是0xcccccc。

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

+0

那不是工作,'lua_pushstring(L“__index”);'实际上是压倒一切的,这将是在元表中可用的方法。如果我在代码的后面调用'luaL_setfuncs(L,Array_metatable,0);',那么索引访问将起作用,但面向对象访问不起作用。 – macroland

+0

一旦你做对了它就会工作......你必须分别添加这两个函数。 –

+0

事实上,我的确可以,请您张贴一些代码,以便我可以了解如何正确执行此操作。 – macroland

注册函数看起来有点乱。

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

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. 
} 
+0

我不知道我在做什么错:代替'lua_setvalue',它不存在于Lua 5.2.4中我使用了'lua_setfield'并且在最后(在返回之前)我添加了'lua_setglobal',否则这个类型不被识别。像arr [1]'这样的调用现在可以工作,但是'arr:get(1)'返回一个错误“#2到'__index'(期望的数字,得到了字符串)”。看起来这个字符串是“get” – macroland