我正在尝试使用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))没有任何运气。有谁知道我在哪里出错?
编辑: 关于如何将键/值推入堆栈的小代码片段。这里的目标是将表从一个表结构移动到另一个表结构(或者我在代码中调用它,重新表示它)
解决方案:
问题是该表有一些metatable函数阻止了对表的更改(实质上,制作脚本的人有一个配置表,其中结构很重要,因此导致了这个问题。)
答案 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;
我还没有开发出一种编写堆栈操作的可读方式。