I\'m trying to load tables from Lua to C++ but I\'m having trouble getting it right. I\'m getting through the first iteration just fine but then at the second call to lua_ne
Why are you doing the extra lua_pop(L, 1)
at the end of the version from the reference manual? I can see how that could be a problem, since you're popping beyond the stack depth.
When you call lua_next
, the second argument should be the index of the table. Since you're just pushing the table onto the stack with
lua_getglobal(L, "level");
after that call your stack will look like
-1: table "level"
(not +1
, since the stack is read going down). Then you call
lua_pushnil(L);
so your stack will be
-1: key (nil) -2: table "level"
Your table is at -2
, so when you call lua_next
, you should use the index -2
. Finally, after each iteration, your stack should look like:
-1: value -2: key -3: table "level"
So you want to read the value (at -1
) and then pop it (so just pop once), and then call lua_next
to get the next key. So something like this should work:
lua_getglobal(L, "level");
lua_pushnil(L);
while(lua_next(L, -2)) { // <== here is your mistake
if(lua_isnumber(L, -1)) {
int i = (int)lua_tonumber(L, -1);
//use number
}
lua_pop(L, 1);
}
lua_pop(L, 1);
Edit based on your second edit
Since it works when you remove external stuff, but doesn't when you add it back in, my best guess is that you're corrupting the stack somehow (either the C++ stack or the lua stack). Look really carefully at your pointers, especially when you manipulate the lua state.
Reading LUA manual lua_next you find that problems may arise on using lua_tostring on a key directly, that is you have to check the value of the key and then decide to use lua_tostring or lua_tonumber. So you could try this code:
std::string key
while(lua_next(L, -2) != 0){ // in your case index may not be -2, check
// uses 'key' (at index -2) and 'value' (at index -1)
if (lua_type(L, -2)==LUA_TSTRING){ // check if key is a string
// you may use key.assign(lua_tostring(L,-2));
}
else if (lua_type(L, -2)==LUA_TNUMBER){ //or if it is a number
// this is likely to be your case since you table level = { 1, 2, 3, }
// don't declare field ID's
// try:
// sprintf(buf,"%g",lua_tonumber(L,-2));
// key.assign(buf);
}
else{
// do some other stuff
}
key.clear();
lua_pop(L,1)
}
Hope it helps.