Я создаю функцию C / C ++, которая будет вызываться из Lua. Моя функция должна вызывать библиотечную функцию, подпись которой выглядит следующим образом:
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;
Может быть, мои мысли об этом неверны, но из Луа я звоню так:
id = 42
val1 = 1
val2 = 2
cmd1 = { 3, 4 }
cmd2 = { 5, 6 }
commands = { cmd1, cmd2 }
settings = { #commands, id, commands }
mycfunction( val1, val2, settings )
Я уверен, что я все еще не понимаю стек Lua, на который ссылается C ++, поскольку то, что я пытаюсь, просто не работает. Мое решение может получить val1, val2, #commands и id, но когда я пытаюсь получить команды [0] и команды [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 раза значения 2 и 42 присваиваются v. Следующие 2 итерации пропускают присваивание (lua_istable вернул true). Так что, похоже, что я уже получил numcmds а также Я бы, они все еще там в стеке. Я также явно не понимаю, как перебирать субтаблицы, когда они встречаются.
Индексы таблицы 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
не нужно проходить
Других решений пока нет …