在C api中移动lua表

时间:2013-06-20 19:32:14

标签: c++ lua lua-table lua-api

我正在尝试使用lua C api将表移动到另一个表。例如,我有一个具有这种结构的表:

a[b][c][d][e] = value

我想把表d移到a [b]下,我可以在Lua中完成:

a[b][d] = a[b][c][d]
a[b][c][d] = nil

我目前的方法是在堆栈上加载a [b] [c] [d]表,所以堆栈看起来像:

Index  Value
-1     d table
-2     c table
-3     b table
-4     a table

然后将[b]加载到堆栈上,如下所示:

Index  Value
-1     b table
-2     a table
-3     d table
-4     c table
-5     b table
-6     a table

然后将d's键放入堆栈,并在表d下插入d's键和表b,因此堆栈为:

Index  Value
-1     d table
-2     d key
-3     b table
-4     a table
-5     c table
-6     b table
-7     a table

然后我用lua_settable(L,-3)来做b [d] = d。

此方法适用于非表键,但对于作为表的键则失败。所以它会失败,例如:

a[b][c][{}][d] = value
a[b] = a[b][c][{}][d]

注意,我知道在上面的lua中会失败,因为键是一个新的lua表,我只是想说明它。

我试过去父母的桌子(所以做一个[b] = b,lua_setglobal(L,a))没有任何运气。有谁知道我在哪里出错?

编辑: 关于如何将键/值推入堆栈的小代码片段。这里的目标是将表从一个表结构移动到另一个表结构(或者我在代码中调用它,重新表示它)

http://pastebin.com/Y4540Wss

解决方案:

问题是该表有一些metatable函数阻止了对表的更改(实质上,制作脚本的人有一个配置表,其中结构很重要,因此导致了这个问题。)

1 个答案:

答案 0 :(得分:1)

如果我正确理解您的描述,这个Lua代码可以满足您的需求:

local ab = a[b]
ab[d], ab[c][d] = ab[c][d], nil

至于在Lua C API中实现,lua2c对此机器翻译很有帮助:

enum { lc_nformalargs = 0 };
const int lc_nactualargs = lua_gettop(L);
const int lc_nextra = (lc_nactualargs - lc_nformalargs);

/* local ab = a[b] */
lua_getfield(L,LUA_ENVIRONINDEX,"a");
lua_getfield(L,LUA_ENVIRONINDEX,"b");
lua_gettable(L,-2);
lua_remove(L,-2);
assert(lua_gettop(L) - lc_nextra == 1);

/* ab[d], ab[c][d] = ab[c][d], nil */
lua_getfield(L,LUA_ENVIRONINDEX,"c");
lua_gettable(L,(1 + lc_nextra));
lua_getfield(L,LUA_ENVIRONINDEX,"d");
lua_gettable(L,-2);
lua_remove(L,-2);
lua_pushnil(L);
lua_getfield(L,LUA_ENVIRONINDEX,"c");
lua_gettable(L,(1 + lc_nextra));
lua_insert(L,-2);
lua_getfield(L,LUA_ENVIRONINDEX,"d");
lua_insert(L,-2);
lua_settable(L,-3);
lua_pop(L,1);
lua_getfield(L,LUA_ENVIRONINDEX,"d");
lua_insert(L,-2);
lua_settable(L,(1 + lc_nextra));
assert(lua_gettop(L) - lc_nextra == 1);
return 0;

我还没有开发出一种编写堆栈操作的可读方式。