2010-02-08 15 views
5

Come passare una tabella di lunghezza sconosciuta da Lua a una funzione C++ associata?Come passare un tavolo da Lua in C++?

Voglio essere in grado di chiamare la funzione Lua in questo modo:

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

e copiare il contenuto della tabella in un array (preferibilmente STL vector)?

+0

Si sta usando solo la cruda Lua c-api? O stai usando una delle tante librerie ToLua, lua ++, luabind? I dettagli della risposta dipenderanno dal tuo approccio –

risposta

3

Se si utilizza LuaBind è semplice come una chiamata registrata. Per quanto riguarda il rollover, è necessario dare un'occhiata alla funzione lua_next.

In pratica il codice è il seguente:

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 
} 
+2

L'uso di lua_next() è corretto? Per la funzione next() il manuale Lua afferma "L'ordine in cui gli indici sono enumerati non è specificato, anche per gli indici numerici." Se questo vale anche per lua_next(), potresti non ottenere i valori nell'ordine previsto. – mkluwe

-1

È inoltre possibile utilizzare lua_objlen:

Restituisce la "lunghezza" del valore al dato indice accettabile: per archi, questo è la stringa lunghezza; per le tabelle, questo è il risultato dell'operatore di lunghezza ('#'); per userdata, questa è la dimensione del blocco di memoria allocata per il dato utente ; per altri valori, è 0.

+0

D: Come faccio a passare un tavolo da lua a C++? A: Usa 'lua_objlen'. – cubuspl42

2

Questo sarebbe il mio tentativo (senza controllo degli errori):

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; 
}