在 C api 中移动 Lua 表

我正在尝试使用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]表加载到堆栈上,堆栈看起来像:

索引 值
-1     d table
-2     c table
-3     b table
-4     a table

然后将a[b]加载到堆栈上,它看起来像:

索引 值
-1     b table
-2     a table
-3     d table
-4     c table
-5     b table
-6     a table

然后将d的键放到堆栈上,并将d的键和表b插入到表d下面,使堆栈变为:

索引 值
-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

解决方案:

问题是该表有一些元表函数,防止对表进行更改(本质上,编写脚本的人有一个重要的结构配置表,因此导致此问题)。

点赞
用户2226988
用户2226988

如果我理解你的描述正确的话,这段 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-20 20:53:47