在 C++ 中访问 Lua 表中的嵌套表

我试图传输包含嵌套表的表格从 Lua 并写入 .ini 文件。但是我不知道该如何在堆栈上进行才能从嵌套表中获取数据。这段代码不像应该的那样工作。函数 setData 没有正确工作。问题可能是什么?

C++ 代码

int sasl::LuaUtilities::luaWriteIni(LuaState inOutState)
{
    string path;
    boost::property_tree::ptree iniTree;
    LUA_CHECK_NARG_EQ(inOutState, 2);
    LUA_GET_PARAM(inOutState, 1, path);
    int nargs = lua_gettop(inOutState);
    for (int i = 1; i <= nargs; i++) {
        if (lua_istable(inOutState, nargs)) {
            setData(inOutState, nargs, iniTree);
        }
    }
    return 0;
}

void sasl::LuaUtilities::setData(LuaState inOutState, int index, boost::property_tree::ptree & inIniTree)
{
    // Push an initial nil to init lua_next
    lua_pushnil(inOutState);
    // Parse the table at index
    while (lua_next(inOutState, index))
    {
        if (lua_istable(inOutState, index))
        {
            setData(inOutState, index, inIniTree);
        }
        else
        {
            string key = lua_tostring(inOutState, -2);
            string value = lua_tostring(inOutState, -1);
        }
        // Pop value, keep key
        lua_pop(inOutState, 1);
    }
    return;
}

Lua 代码

t = {}
local fileName = findResourceFile("test.ini")
t = readINI(fileName)
writeINI(fileName, t) --这在 C++ 中不起作用
点赞
用户734069
用户734069

有两个问题。lua_istable(inOutState, index) 是错误的,因为 index 不是通过 next 检索到的键的值。那个索引始终是您正在迭代的表。因此,在使用该索引调用 setData 时,您将无限递归相同的表。

实际上,将 index 传递给 setData 几乎肯定是错误的。或者至少,可能不正确。您想在这里使用相对索引,但调用 next 会将额外的值推送到堆栈上。

您可能要做的是让 setData 假定要迭代的表位于索引 -1(即:堆栈顶部)。这样,您只需调用 lua_next(state, -2)(因为要获取下一个键的键在顶部)。当您为表值递归调用 setData 时,您不需要提供索引,因为表值已经在堆栈的顶部。

第二个问题是您从未写入键/值对。您也从未检查值是否可以转换为字符串。它可能是 Lua 用户数据。

2020-03-02 16:14:49