2

我正在尝试使用 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

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

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

然后将d的key放入栈中,将d的key和表b插入到表d下,所以栈为:

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 表,我只是想说明一下。

我已经尝试过从父母那里下去(这样做a [b] = b,lua_setglobal(L,a))也没有任何运气。有谁知道我要去哪里错了?

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

http://pastebin.com/Y4540Wss

解决方案:

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

4

1 回答 1

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;

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

于 2013-06-20T20:53:47.287 回答