2009-10-27 17 views
8

Voglio creare una tabella comeCome creare tabelle nidificate Lua utilizzando l'API C

myTable = { 
    [0] = { ["a"] = 4, ["b"] = 2 }, 
    [1] = { ["a"] = 13, ["b"] = 37 } 
} 

utilizzando l'API C?

Il mio approccio attuale è

lua_createtable(L, 0, 2); 
int c = lua_gettop(L); 
lua_pushstring(L, "a"); 
lua_pushnumber(L, 4); 
lua_settable(L, c); 
lua_pushstring(L, "b"); 
lua_pushnumber(L, 2); 
lua_settable(L, c); 

per creare le tabelle interne in un ciclo. Prima, in questo ciclo, utilizzo

lua_createtable(L, 2, 0); 
int outertable = lua_gettop(L); 

per creare il tavolo esterno per 2 slot numerici.

Ma come posso salvare i tavoli interni sul tavolo esterno?

risposta

17

Ecco un programma completo e minimale che mostra come nidificare le tabelle. Fondamentalmente ciò che ti manca è la funzione lua_setfield.

#include <stdio.h> 
#include "lua.h" 
#include "lauxlib.h" 
#include "lualib.h" 

int main() 
{ 
    int res; 
    lua_State *L = lua_open(); 
    luaL_openlibs(L); 

    lua_newtable(L); /* bottom table */ 

    lua_newtable(L); /* upper table */ 

    lua_pushinteger(L, 4); 
    lua_setfield(L, -2, "four"); /* T[four] = 4 */ 
    lua_setfield(L, -2, "T"); /* name upper table field T of bottom table */ 
    lua_setglobal(L, "t"); /* set bottom table as global variable t */ 

    res = luaL_dostring(L, "print(t.T.four == 4)"); 
    if(res) 
    { 
     printf("Error: %s\n", lua_tostring(L, -1)); 
    } 

    return 0; 
} 

Il programma sarà sufficiente stampare true.

Se avete bisogno di indici numerici, quindi si continua con lua_settable:

#include <stdio.h> 
#include "lua.h" 
#include "lauxlib.h" 
#include "lualib.h" 

int main() 
{ 
    int res; 
    lua_State *L = lua_open(); 
    luaL_openlibs(L); 

    lua_newtable(L); /* bottom table */ 

    lua_newtable(L); /* upper table */ 

    lua_pushinteger(L, 0); 
    lua_pushinteger(L, 4); 
    lua_settable(L, -3); /* uppertable[0] = 4; pops 0 and 4 */ 
    lua_pushinteger(L, 0); 
    lua_insert(L, -2); /* swap uppertable and 0 */ 
    lua_settable(L, -3); /* bottomtable[0] = uppertable */ 
    lua_setglobal(L, "t"); /* set bottom table as global variable t */ 

    res = luaL_dostring(L, "print(t[0][0] == 4)"); 
    if(res) 
    { 
     printf("Error: %s\n", lua_tostring(L, -1)); 
    } 

    return 0; 
} 

Invece di utilizzare gli indici assoluti di 0 come ho fatto io, si potrebbe desiderare di utilizzare lua_objlen per generare l'indice.

+0

come creare gli indici numerici con lua_setfield? – Etan

8

Per semplice codice come quello che hai dato, la mia lua2c funziona bene e genera il codice qui sotto.

/* This C code was generated by lua2c from the Lua code below. 

myTable = { 
    [0] = { ["a"] = 4, ["b"] = 2 }, 
    [1] = { ["a"] = 13, ["b"] = 37 } 
} 
*/ 
static int MAIN(lua_State *L) 
{ 
lua_newtable(L); 
lua_pushnumber(L,0); 
lua_newtable(L); 
lua_pushliteral(L,"a"); 
lua_pushnumber(L,4); 
lua_pushliteral(L,"b"); 
lua_pushnumber(L,2); 
lua_settable(L,-5); 
lua_settable(L,-3); 
lua_pushnumber(L,1); 
lua_newtable(L); 
lua_pushliteral(L,"a"); 
lua_pushnumber(L,13); 
lua_pushliteral(L,"b"); 
lua_pushnumber(L,37); 
lua_settable(L,-5); 
lua_settable(L,-3); 
lua_settable(L,-5); 
lua_settable(L,-3); 
lua_setglobal(L,"myTable"); 
return 0; 
} 
2

Ecco qualcosa di generico. Mi sono inventato per risolvere un problema simile, basato sulla risposta di lhf. Ciò creerà una tabella Lua per il modulo

{ 
    {"foo"}, 
    {"bar", "baz"} 
} 

Con tabella arbitraria/tabella secondaria lunghezza.

int list_of_lists_to_lua(lua_State* L, const std::vector<std::vector<std::string>>& convertme) { 
    lua_newtable(L); 
    int counter = 0; 
    for (const std::vector<std::string>& list : convertme) { 
     lua_pushnumber(L, ++counter); 
     lua_newtable(L); 
     int counter2 = 0; 
     for (const std::string& item : list) { 
      lua_pushnumber(L, ++counter2); 
      lua_pushstring(L, item); 
      lua_settable(L,-3); 
     } 
     lua_settable(L,-3); 
    } 
    return 1; 
} 
+0

Non assomiglia a C. Né compilare senza inclusi. – Kamiccolo

+0

Questo è C++ che utilizza l'eris. – GunChleoc

Problemi correlati