Iterating through a Lua table from C++?

前端 未结 3 1243
忘掉有多难
忘掉有多难 2020-12-01 02:30

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

相关标签:
3条回答
  • 2020-12-01 02:58

    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.

    0 讨论(0)
  • 2020-12-01 02:59

    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.

    0 讨论(0)
  • 2020-12-01 03:01

    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.

    0 讨论(0)
提交回复
热议问题