【问题标题】:C++ Lua (table of table of objects)C++ Lua(对象表)
【发布时间】:2015-08-08 07:23:34
【问题描述】:

我想将对象向量的向量转换为 Lua 中的对象表。

所以我在 lua 中有一个简单的脚本:

objects = getObjects()
explosion = objects[1][1]:getDestructible()
print (explosion)

这是我的 .cpp 文件

std::vector<std::vector<Area> > objects;
int x;
int y;

y = 0;
lua_newtable(L);
for (std::vector<std::vector<Area> >::iterator it = objects.begin(); it != objects.end(); ++it)
{
    lua_createtable(L, 2, 0);
    x = 0;
    for (std::vector<Area>::iterator it2 = it->begin(); it2 != it->end(); ++it2)
    {
        lua_newtable(L);
        luaL_getmetatable(L, "luaL_Object");
        lua_setmetatable(L, -2);
        lua_rawseti(L, -2, x + 1);
        x++;
    }
    lua_rawseti(L, -2, y);
    y++;
}

当我运行脚本时,我总是会得到类似“尝试索引零索引”的信息。我错过了什么吗?

【问题讨论】:

  • 你在哪里将实际对象推入堆栈,然后将其放入内表?您创建外部表,然后创建内部表并为它们提供元表,但您永远不会用任何内容填充它们(或者元表是否应该处理该访问?)。如果是这种情况,您确定元表正在工作吗?如果将索引拆分为多个步骤,哪个步骤会失败?
  • 是的,元表包含所有我想使用的方法我很确定它可以工作,因为它可以用于简单的向量列表。我不确定如何测试哪个步骤失败?我的意思是这不只是索引的问题吗?
  • @Alex:你的 Lua 堆栈在内部循环中仍然不平衡:你压入一个值(luaL_getmetatable),然后弹出一个值(lua_setmetatable),然后弹出另一个值( lua_rawseti)。您可能在luaL_getmetatable 之前缺少lua_newtablelua_newuserdata。最后一个lua_rawseti 中的堆栈索引也应该是-2
  • @siffiejoe:我已经调整了我上面的代码,考虑到你在说什么,但我有点迷茫,我也尝试了 print(type(objects[1])) 这给了我 nil ,所以第一个索引不起作用......有什么想法吗?!
  • 与您的内部lua_rawseti(L, -2, x + 1); x++; 相比,外部lua_rawseti(L, -2, y); y++; 可能存在一个错误

标签: c++ scripting lua


【解决方案1】:

感谢大家的帮助!我终于找到了我的问题的答案,就是这样:

int Lua::luaGetObjects(lua_State *L)
{
    int x;
    int y;

    y = 0;
    lua_newtable(L);
    for (std::vector<std::vector<Area> >::iterator it2 = objects.begin(); it2 != objects.end(); ++it2)
    {
        x = 0;
        lua_newtable(L);
        for (std::vector<Area>::iterator it = it2->begin(); it != it2->end(); it++, x++) 
        {

            lua_pushnumber(L, x);

            luaL_getmetatable(L, "luaL_Object");
            lua_setmetatable(L, -2);

            lua_rawseti(L, -2, x + 1);
            x++;
        }
        lua_rawseti(L, -2, y + 1);
        y++;
    }
    return 1;
}

我终于可以用它打电话了:

objects = getObjects()
explosion = objects[1][1]:getExplosion()
print(explosion)

【讨论】:

  • 如果你执行objects = getObjects(); print( (0):getExplosion() )会发生什么,objects[1][1]:getExplosion()的结果是否与objects[2][1]:getExplosion()相同?
  • @siffiejoe:嘿,我用第一个索引试验了你肯定谈论的问题:/ 你知道如何抓住它吗?无论如何,我完全改变了我的算法,只需设置一个包含我所有 cpp getter 的元表,它们采用两个参数,我最终可以用luaL_checknumber(L, 2)luaL_checknumber(L, 3) 捕获,所以现在我调用objects:getExplosion(x, y) 我想创建它更有效只有一个对象,而不是一个对象表。现在一切正常,再次感谢您!
  • Lua 中的所有数字共享一个公共元表,因此当您在内循环中在x 上设置一个元表时,所有数字突然都可以使用您的方法。这就是(0):getExplosion() 起作用的原因。同样objects[1][1]objects[2][1] 的值在这两种情况下都是0,因此方法调用getExplosion() 应该返回相同的结果(实际上与(0):getExplosion() 的结果相同)。您的新方法要好得多。
猜你喜欢
  • 2021-07-15
  • 2020-05-28
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 2015-02-07
  • 2010-10-24
  • 1970-01-01
  • 2019-02-18
相关资源
最近更新 更多