2010-12-26 10 views
4

Es gibt eine Menge Beispiele, wie man eine Lua-Tabelle in Lua klonen kann, aber ich konnte kein Beispiel finden, wie man es mit der nativen Lua C-API macht. Ich habe zweimal versucht, es mit der Hand zu machen, aber es endete mit einem echten (wenn auch funktionierenden) Durcheinander.Klonen einer Lua-Tabelle in Lua C API

Hat jemand irgendwelche Tipps oder Links, wie man eine flache Kopie einer Lua-Tabelle in der C-API elegant macht?

Antwort

8

Was Sie tun müssen, ist die Lua-Funktion zu definieren und dann in die zugehörigen API-Aufrufe zu zerlegen.

shallow_copy = function(tab) 
    local retval = {} 
    for k, v in pairs(tab) do 
     retval[k] = v 
    end 
    return retval 
end 

So werden wir den Index einer Tabelle auf dem Stapel und dem lua_State zu nehmen brauchen.

void shallow_copy(lua_State* L, int index) { 

/*Create a new table on the stack.*/ 

     lua_newtable(L); 

/*Now we need to iterate through the table. 
Going to steal the Lua API's example of this.*/ 

     lua_pushnil(L); 
     while(lua_next(L, index) != 0) { 
/*Need to duplicate the key, as we need to set it 
(one pop) and keep it for lua_next (the next pop). Stack looks like table, k, v.*/ 


      lua_pushvalue(L, -2); 
/*Now the stack looks like table, k, v, k. 
But now the key is on top. Settable expects the value to be on top. So we 
need to do a swaparooney.*/ 

      lua_insert(L, -2); 

    /*Now we just set them. Stack looks like table,k,k,v, so the table is at -4*/ 



    lua_settable(L, -4); 

/*Now the key and value were set in the table, and we popped off, so we have 
table, k on the stack- which is just what lua_next wants, as it wants to find 
the next key on top. So we're good.*/ 

     } 
    } 

Jetzt befindet sich unser kopierter Tisch oben auf dem Stapel.

Christus, der Lua API saugt.

+1

Woah, vergiss die Austauschmöglichkeit von lua_insert! Danke vielmals :). Und nein, ich denke nicht, dass es scheiße ist - wenn man bedenkt, dass wir so komplexe Sachen mit einer C-Level-Sprache machen können ... –

+0

Man sollte auch beachten, dass dies nur mit einem absoluten Index funktioniert, vielleicht ein Aufruf von 'lua_absindex 'wäre in Ordnung. –

+0

@Kornel: Es saugt, weil Sie mit Objektorientierung viel besser machen können. Bei jedem Schritt des Schreibens jeder Lua-Interaktionsfunktion müssen Sie praktisch aufschreiben, was auf dem Stapel ist. Es wäre weitaus besser, wenn die Lua-API in irgendeiner Weise objektorientiert wäre, außer dem lua_State. Es ist so, als hätten sie gelernt, anständigen Code zu schreiben, und dann auf halbem Weg vergessen. – Puppy