我的问题与此类似: How to create nested Lua tables using the C API
我认为我明白这个答案,但我仍然有问题。
我有一系列对象,我正试图返回。
const char * pushlist[] = {
"status", "cmdsequence", "timestamp", "gain",
};
int nItems = sizeof(pushlist) / sizeof(char *);
int iDepth = -(1 + nItems);
// //
// What we want to do is essentially push an array of tables.
// The tables have keys (see pushlist above) and values.
// The array is indexed by integers from 1 through N.
//
lua_newtable( L );
for( Json::Value::UInt i = 0; i != totFrames; i++ )
{
lua_pushnumber( L, i + 1 ); // push the array index
lua_newtable( L );
Json::Value frame = params["frameinfo"][i];
// now push the table which will be at array index (i + 1)
for( int n = 0; n < nItems; n++ )
{
lua_pushstring( L, pushlist[n] ); // push key
lua_pushnumber( L, frame[pushlist[n]].asUInt() ); // push value
}
lua_settable(L, iDepth);
lua_settable(L, -3); // (note 1) error here
}
lua_settable(L, iDepth); // (note 2) not clear on the need for this
lua_settable(L, -3);
lua_setglobal( L, "framedata" );
所以在Lua我想看到:
[0] = {[“status”] = 1,[“cmdsequence”] = 2,[“timestamp”] = 3,[“gain”] = 4}
...
[totFrames-1] = {[“status”] = 5,[“cmdsequence”] = 6,[“timestamp”] = 7,[“gain”] = 8}
我不清楚注2中2 lua_settable是什么,但我上面提到的答案表明他们是需要的。
lua_settable(L,-3)(注1)错误输出。我在C ++中这样做,所以我把这个代码放在try / catch中。当它第一次出现并击中我的捕获时它击中了那个可设置的。我想我已经以某种方式破坏了堆栈,但我没有看到它。
感谢@Omri Barel的出色答案。在内部'for'循环之后,我仍然不清楚要做什么。
我现在有这个: const char * pushlist [] = { “status”,“cmdsequence”,“timestamp”,“gain”, }; int nItems = sizeof(pushlist)/ sizeof(char *);
// //
// What we want to do is essentially push an array of tables.
// The tables have keys (see pushlist above) and values.
// The array is indexed by integers from 1 through N.
//
lua_newtable( L );
for( Json::Value::UInt i = 0; i != totFrames; i++ )
{
lua_pushnumber( L, i + 1 ); // push the array index
lua_newtable( L );
Json::Value frame = params["frameinfo"][i];
// now push the table which will be at array index (i + 1)
for( int n = 0; n < nItems; n++ )
{
lua_pushnumber( L, frame[pushlist[n]].asDouble() ); // push value
lua_setfield(L, -2, pushlist[n] );
}
lua_settable(L, -3); // (note 1) error here
}
//lua_settable(L, -3); <<-- not certain that this is required
lua_setglobal( L, "framedata" );
我不再爆炸,但我的Lua失败了(没有错误消息,它只是退出)。我怀疑我没有损坏堆栈,但不知怎的,我没有正确完成这个表,所以我的回报很困惑。
我在此数组之前将几个其他返回值推送到Lua堆栈中,然后再推送一个返回值。
我的Lua电话是这样的:
param1,param2,framedata,Err = CCall.ReadFromC( arg, arg );
我终于有了这个工作。它需要进一步测试,但到目前为止似乎是正确的。再次感谢@Omri Barel。这是我最终得到的代码片段。
const char * pushlist[] = {
"status", "cmdsequence", "timestamp", "gain",
};
int nItems = sizeof(pushlist) / sizeof(char *);
// //
// What we want to do is essentially push an array of tables.
// The tables have keys (see pushlist above) and values.
// The array is indexed by integers from 1 through N.
//
lua_newtable( L );
for( Json::Value::UInt i = 0; i != totFrames; i++ )
{
Json::Value frame = params["frameinfo"][i];
// now push the table which will be at array index (i + 1)
lua_newtable( L );
for( int n = 0; n < nItems; n++ )
{
const char * itemName = pushlist[n];
if( frame[itemName].isNull() ) continue;
lua_pushnumber( L, frame[pushlist[n]].asDouble() ); // push value
lua_setfield(L, -2, pushlist[n] );
}
lua_rawseti(L, -2, i + 1);
}
答案 0 :(得分:6)
问题是在将它们添加到表之前,您正在推送太多的键/值对。你应该一次添加一对。
调试Lua时,你可以做的最好的事情是经常转储堆栈的内容,检查发生了什么。 “Programming In Lua”中有一些“堆栈转储”代码(第一版就足够了)。
让我们来看看你的代码(在循环内部)。
您创建一个表。堆栈是:
... [table]
您推送键/值对:
... [table] [key] [value] [key] [value] [key] [value] [key] [value]
您使用iDepth
调用settable,这对我来说不合适。在这种情况下iDepth = -(1+nItems) = -5
。但是你正在推动对,所以它应该是双倍的。但即使iDepth
是正确的,你仍然只调用一次,所以它只从堆栈中删除一对:
... [table] [key] [value] [key] [value] [key] [value]
您使用-3调用settable,但-3是[value],因此您会收到错误。
你应该在每个键/值对之后调用settable(带-3)。
我还建议使用setfield
,这有点清楚。而不是:
lua_pushstring(L, key);
lua_pushnumber(L, value);
lua_settable(L, -3);
您可以使用:
lua_pushnumber(L, value);
lua_setfield(L, -2, "key");