6

How would I pass a table of unknown length from Lua into a bound C++ function?

I want to be able to call the Lua function like this:

call_C_Func({1,1,2,3,5,8,13,21})

And copy the table contents into an array (preferably STL vector)?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
GameFreak
  • 2,881
  • 7
  • 34
  • 38
  • Are you just using the raw Lua c-api? Or are you using one of the many libraries ToLua, lua++, luabind? The details of the answer will depend on your approach – Andrew Walker Feb 08 '10 at 05:27

3 Answers3

3

If you use LuaBind it's as simple as one registered call. As for rolling up your own, you need to take a look at lua_next function.

Basically the code is as follows:

lua_pushnil(state); // first key
index = lua_gettop(state);
while ( lua_next(state,index) ) { // traverse keys
  something = lua_tosomething(state,-1); // tonumber for example
  results.push_back(something);
  lua_pop(state,1); // stack restore
}
Kornel Kisielewicz
  • 55,802
  • 15
  • 111
  • 149
  • 2
    Is the usage of lua_next() correct? For the next() function the Lua manual states "The order in which the indices are enumerated is not specified, even for numeric indices." If this is true for lua_next() as well you might not get the values in the expected order. – mkluwe Feb 12 '10 at 14:19
3

This would be my attempt (without error checking):

int lua_test( lua_State *L ) {
    std::vector< int > v;
    const int len = lua_objlen( L, -1 );
    for ( int i = 1; i <= len; ++i ) {
        lua_pushinteger( L, i );
        lua_gettable( L, -2 );
        v.push_back( lua_tointeger( L, -1 ) );
        lua_pop( L, 1 );
    }
    for ( int i = 0; i < len; ++i ) {
        std::cout << v[ i ] << std::endl;
    }
    return 0;
}
mkluwe
  • 3,823
  • 2
  • 28
  • 45
-1

You can also use lua_objlen:

Returns the "length" of the value at the given acceptable index: for strings, this is the string length; for tables, this is the result of the length operator ('#'); for userdata, this is the size of the block of memory allocated for the userdata; for other values, it is 0.

uroc
  • 3,993
  • 3
  • 21
  • 18