在C api中移动lua表

Moving a lua table in C api

本文关键字:lua 移动 api      更新时间:2023-10-16

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

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

我想把table 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的键放到堆栈中,并将d的键和表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

解决方案:

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

如果我正确理解了你的描述,这段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;

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