[英]Reading Lua nested tables in C++
我正在创建一个将从 Lua 调用的 C/C++ 函数。 我的函数必须调用一个签名如下的库函数:
void libFunction( int val1, int val2, tSETTINGS * pSettings );
我得到了这些 C/C++ 结构:
typedef struct
{
int cmd;
int arg;
} tCOMMAND;
typedef struct
{
int numberCommands;
int id;
tCOMMAND commands[1];
} tSETTINGS;
也许我的想法是完全错误的,但从 Lua 我是这样调用的:
id = 42
val1 = 1
val2 = 2
cmd1 = { 3, 4 }
cmd2 = { 5, 6 }
commands = { cmd1, cmd2 }
settings = { #commands, id, commands }
mycfunction( val1, val2, settings )
我确定我仍然不理解从 C++ 引用的 Lua 堆栈,因为我正在尝试的方法不起作用。 我的解决方案能够检索val1
、 val2
、 #commands
和id
,但是当我尝试检索commands[0]
和commands[1]
我分别得到{1, 2}
和{2, 42}
。
我的 C++ 本质上是这样的(对于这个示例,我丢弃了这些值)。 我已经检索到val1
和val2
:
int stkNdx = 1;
lua_rawgeti(L, 3, stkNdx++ );
int numcmds = lua_tointeger(L, -1); // this successfully retrieves numberCommands 2
lua_pop(L, 1);
lua_rawgeti(L, 3, stkNdx++ );
int id = lua_tointeger(L, -1); // this successfully retrieves id 42
lua_pop(L, 1);
lua_pushvalue(L, -1 );
lua_pushnil(L);
int cmdNbr = 0;
for( lua_next(L, -2); cmdNbr < numcmds; cmdNbr++ )
{
lua_pushvalue(L, -2);
int cmd = lua_tointeger(L, -1);
int arg = lua_tointeger(L, -1);
lua_pop(L, 2);
lua_next(L, -2);
}
lua_pop(L, 1);
我已经试过的各种排列lua_rawgeti()
然后lua_tonumber()
和lua_pop()
有基本相同的结果。
这似乎类似于这个问题,我的解决方案是在此之后建模的,但没有成功。
尝试更多我插入了这个:
lua_pushnil(L);
while( lua_next(L, -2) )
{
if( ! lua_istable(L, -1) )
{
int v = lua_tointeger(L, -1);
}
lua_pop(L, 1);
}
此循环执行 4 次。 值 2 和 42 的前两次分配给v
。 接下来的 2 次迭代跳过赋值(lua_istable 返回 true)。 所以看起来虽然我已经检索了numcmds
和id
,但它们仍然存在于堆栈中。 我也显然不明白如何在遇到子表时对其进行迭代。
Lua 表索引范围从 [1 .. N] 而不是 [0 .. N-1]。
你的循环应该是:
int cmdNbr = 1;
for( lua_next(L, -2); cmdNbr <= numcmds; cmdNbr++ )
{
...
}
或者像我喜欢的那样:
lua_rawgeti(L, 3, 2 );
int id = lua_tointeger(L, -1); // this successfully retrieves id 42
lua_pop(L, 1);
lua_rawgeti(L, 3, 3);
{
// commands table at stack top
size_t N = lua_objlen(L,-1); // size of the table
for (int i = 1; i <= N; ++i)
{
lua_rawgeti(L,-1, i); // cmd# at stack top
{
lua_rawgeti(L,-1,1); // first entry
int cmd = lua_tointeger(L,-1);
lua_pop(L,1);
lua_rawgeti(L,-1,2); // second entry
int arg = lua_tointeger(L,-1);
lua_pop(L,1);
}
lua_pop(L, 1); // pop cmd#
}
}
lua_pop(L, 1); // pop commands table
请注意,对于函数lua_objlen(L,idx)
,没有必要传递numcmds
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.