2010-07-26 4 views
8

Ich habe einige Klassen in C++, die ich an Lua weitergeben möchte. Ich kann Widget:New() anrufen, um Rückkehr userdata mit einem metatable Satz zur Tabelle WidgetMeta zu erhalten. WidgetMeta hat alle C++ Funktionen in sie, und es ist __index sich gesetzt ist, so kann ich dies tun:Behandlung von Userdate wie eine Tabelle in Lua

w = Widget:New() 
w:Foo() -- Foo is defined in C code 

Das ist alles ziemlich einfach ist.

Jetzt ist hier der Teil, den ich nicht herausfinden kann. Ich möchte in der Lage sein, Lua definierte Variablen und Funktionen auf meine Benutzerdaten zu legen, als wäre es eine Tabelle. Dies kann nicht direkt offensichtlich getan werden. Ich kann es nicht auf die Userdata fallen lassen, weil ich möchte, dass es pro Userdata eindeutig ist.

w1 = Widget:New() 
w2 = Widget:New() 

function w1:Bar() print "Hello!" end -- Both functions unique 
function w1:Baz() print "World!" end -- to their own userdata 

Mein aktueller Plan des Angriffs ist die Metatabelle haben eine besondere Tabelle auf sie zu haben, die zwischen Benutzerdaten und Tabelle bildet, wo ich pro-Userdaten Funktionen und Variablen speichern können. Das Problem ist, dass ich nicht sicher bin, was der beste Weg ist, das zu tun, oder ob es eine bessere Lösung gibt. meine Frage ist also zweifacher Art: Wenn ich meine Metadioden __index und __newindex einrichte, schreibe ich sie in Lua-Code in eine Textdatei und führe sie aus, bevor ich den Rest der Dinge ausführe, oder lege ich den Lua-Code direkt von einem C ab string in meinem Programm über luaL_loadstring, oder mache ich das mit der C-Schnittstelle und behandle alle Stapelmanipulationen? und zweitens, wie schreibe ich diese Funktion ... aber ich werde mich darum kümmern, wenn ich erst einmal entschieden habe, welcher der beste Weg ist.

+1

jsimmons' Antwort für Lua 5.1 und früher ist ausgezeichnet, aber in lua 5.2 können Sie eine Tabelle mit jeder Benutzerdaten unter Verwendung von lua_setuservalue assoziieren und abrufen es lua_getuservalue verwenden. Die Antwort von 5.2 würde also derjenigen von jsimmons ähneln, die diese neuen Tabellenzuordnungen anstelle von Funktionsumgebungen verwendet. –

Antwort

9

Fügen Sie den Benutzerdaten eine Funktionsumgebung hinzu, und leiten Sie den Zugriff darauf um.

Hier ist ein alter Code von mir, der den Prozess beschreibt.

static int l_irc_index(lua_State* L) 
{ 
    /* object, key */ 
    /* first check the environment */ 
    lua_getfenv(L, -2); 
    lua_pushvalue(L, -2); 
    lua_rawget(L, -2); 
    if(lua_isnoneornil(L, -1) == 0) 
    { 
     return 1; 
    } 

    lua_pop(L, 2); 

    /* second check the metatable */  
    lua_getmetatable(L, -2); 
    lua_pushvalue(L, -2); 
    lua_rawget(L, -2); 

    /* nil or otherwise, we return here */ 
    return 1; 
} 

static int l_irc_newindex(lua_State* L) 
{ 
    /* object, key, value */ 

    lua_getfenv(L, -3); 
    lua_pushvalue(L, -3); 
    lua_pushvalue(L, -3); 
    lua_rawset(L, -3); 

    return 0; 
} 
+0

Danke, das war viel sauberer als ich es versuchen würde: D – Alex

Verwandte Themen