2017-09-03 1 views
2

Nehmen wir ein einfaches C-Modul für Lua 5.3 mit einem globalen int erstellen:Lua Shared aufzuwerten Beispiel in C

static int l_test(lua_State *L){ 
    int Global = lua_tointeger(L, lua_upvalueindex(1)); 
    Global++; 
    lua_pushinteger(L, Global); 
    lua_pushvalue(L, -1); 
    lua_replace(L, lua_upvalueindex(1)); 
    //lua_pushnumber(L, Global); 
    return 1; 
} 

static int l_anotherTest(lua_State *L){ 
    int Global = lua_tointeger(L, lua_upvalueindex(1)); 
    Global++; 
    Global++; 
    lua_pushinteger(L, Global); 
    lua_pushvalue(L, -1); 
    lua_replace(L, lua_upvalueindex(1)); 
    //lua_pushnumber(L, Global); 
    return 1; 
} 

static const struct luaL_Reg testLib [] = { 
    {"test", l_test}, 
    {"anotherTest", l_anotherTest}, 
    {NULL, NULL} 
}; 

int luaopen_testLib(lua_State *L){ 
    luaL_newlibtable(L, testLib); 
    lua_pushinteger(L, 1); 
    luaL_setfuncs(L, testLib, 1) ;  
    return 1; 
} 

Diese fast funktioniert, aber wenn ich rufe diese beiden Funktion von Lua wie folgt aus:

local testLib = require "testLib" 
print(testLib.test()) 
print(testLib.anotherTest()) 

Der zweite Druck sollte 4 sein, aber es wird ein 3 ausgedruckt. Was mache ich noch falsch?

+1

die aufwerten zu initialisieren, sollten Sie seinen Anfangswert auf den Stapel schieben, kurz bevor 'setfuncs' aufrufen. Um auf den upvalue von 'l_test' zuzugreifen, sollten Sie' lua_upvalueindex (1) 'verwenden, um den Stack-Pseudoindex zu erhalten, in dem sich dieser Wert befindet. –

+0

Danke für den Hinweis. Ich habe die Frage aktualisiert. Hier fehlt noch etwas. Kannst du mir helfen? – user1511417

+0

Verwenden Sie das 'NULL'-Makro, wenn Sie eine Null-Zeiger-Konstante möchten. Die Verwendung der Ganzzahl "0" ist ein fehlgeleitetes Vermächtnis. – Olaf

Antwort

3

Upwerte von C-Verschlüsse werden nicht geteilt, nur Upwerte von Lua-Verschlüsse sind. Jedes C-Closing enthält seine Upvalues ​​direkt (siehe here). Wenn Sie Werte für zwei oder mehr C-Closures gemeinsam verwenden möchten, verwenden Sie eine einzige allgemeine Tabelle als Upvalue für alle und geben Sie Ihre gemeinsamen Werte dort ein oder verwenden Sie stattdessen die Registrierung für Ihre freigegebenen Daten.

etwas wie das folgende tun sollten, was Sie wollen:

#include <lua.h> 
#include <lauxlib.h> 


/* getint and setint may only be called from Lua C functions that 
* have the shared table as upvalue 1. 
*/ 

static int getint(lua_State *L){ 
    int v = 0; 
    lua_getfield(L, lua_upvalueindex(1), "myint"); 
    v = lua_tointeger(L, -1); 
    lua_pop(L, 1); /* remove integer from stack */ 
    return v; 
} 

static void setint(lua_State *L, int v){ 
    lua_pushinteger(L, v); 
    lua_setfield(L, lua_upvalueindex(1), "myint"); 
} 


static int l_test(lua_State *L){ 
    int Global = getint(L); 
    Global++; 
    setint(L, Global); 
    lua_pushinteger(L, Global); 
    return 1; 
} 

static int l_anotherTest(lua_State *L){ 
    int Global = getint(L); 
    Global++; 
    Global++; 
    setint(L, Global); 
    lua_pushinteger(L, Global); 
    return 1; 
} 

static const struct luaL_Reg testLib [] = { 
    {"test", l_test}, 
    {"anotherTest", l_anotherTest}, 
    {NULL, NULL} 
}; 

int luaopen_testLib(lua_State *L){ 
    luaL_newlibtable(L, testLib); 
    lua_newtable(L); 
    lua_pushinteger(L, 1); 
    lua_setfield(L, -2, "myint"); 
    luaL_setfuncs(L, testLib, 1); 
    return 1; 
} 
+0

@siffiejoe - 'luaL_setfuncs' ermöglicht es Ihnen, Upgrades unter allen C-Funktionen zu registrieren. Dies versucht OP zu erreichen. –

+2

@EgorSriptunoff: Alle C-Closures aus dem 'luaL_setfuncs'-Aufruf haben danach die gleichen Upvalues, aber diese Upvalues ​​sind ** nicht ** geteilt, dh die Änderung der Upvalues ​​eines Closures hat keinen Einfluss auf die Upvalues ​​der anderen Closures, * außer *, wenn Sie Werte ändern, die durch Referenzen wie Tabellen, Benutzerdaten usw. übergeben werden (alle Schließungen haben separate Referenzen auf dieselbe Tabelle/userdata/...). – siffiejoe

+1

Ich habe einen alten Mailinglisten-Thread für Sie ausgegraben: http://lua-users.org/lists/lua-l/2006-08/msg00189.html – siffiejoe