2010-04-25 19 views

Odpowiedz

5
void register_c_function(char const * const tableName, char const * const funcName, CFunctionSignature funcPointer) 
{ 
    lua_getfield(lstate, LUA_GLOBALSINDEX, tableName); // push table onto stack 
    if (!lua_istable(lstate, -1))      // not a table, create it 
    { 
     lua_createtable(lstate, 0, 1);  // create new table 
     lua_setfield(lstate, LUA_GLOBALSINDEX, tableName); // add it to global context 

     // reset table on stack 
     lua_pop(lstate, 1);     // pop table (nil value) from stack 
     lua_getfield(lstate, LUA_GLOBALSINDEX, tableName); // push table onto stack 
    } 

    lua_pushstring(lstate, funcName);  // push key onto stack 
    lua_pushcfunction(lstate, funcPointer); // push value onto stack 
    lua_settable(lstate, -3);    // add key-value pair to table 

    lua_pop(lstate, 1);      // pop table from stack 
} 
+4

Dlaczego po prostu nie używać luaL_register? – uroc

20

To co luaL_register() przeznaczony jest do zrobienia, dla jednego lub większej liczby funkcji. Wykorzystanie kanoniczna jest jako część konfiguracji dla modułu napisanego w C:

/* actual definitions of modA() and modB() are left as an exercise. */ 

/* list of functions in the module */ 
static const luaL_reg modfuncs[] = 
{ 
    { "a", modA}, 
    { "b", modB}, 
    { NULL, NULL } 
}; 

/* module loader function called eventually by require"mod" */ 
int luaopen_mod(lua_State *L) { 
    luaL_register(L, "mod", modfuncs); 
    return 1; 
} 

gdzie ten tworzy moduł o nazwie „mod”, który ma dwie funkcje o nazwach mod.a i mod.b.

Cytując instrukcję dla luaL_register(L,libname,l):

Wywołany z libname równej NULL, to po prostu rejestruje wszystkie funkcje na liście l (patrz luaL_Reg) w tabeli na górze stosie .

Wywołany z niepuste libname, luaL_register tworzy nową tabelę t, ustawia go jako wartość globalnego zmiennej libname, ustawia go jako wartość z package.loaded[libname] i rejestry na nim wszystkie funkcje na liście lista l. Jeśli w tabeli znajduje się tabela package.loaded[libname] lub zmienna libname, ponownie korzysta z tej tabeli zamiast , tworząc nową.

W każdym przypadku funkcja opuszcza tabelę na szczycie stosu.

luaL_register() mogą być wykorzystane do umieszczenia funkcji C w każdej tabeli przepuszczając NULL do drugiego parametru, o ile tablica jest na górze stosu.

+0

Jeśli istnieje już tabela mod z innymi polami, czy zostanie ona rozszerzona lub zastąpiona nową po wywołaniu luaL_register()? –

+0

to ponownie wykorzysta i zaktualizuje poprzednią tabelę, zgodnie z instrukcją 5.1. – u0b34a0f6ae

+0

Niezależnie od tego, czy zostanie zastosowana do nazwanej tabeli globalnej, czy do tabeli u góry stosu, ustawia tylko te pola, które zostały wymienione na liście funkcji do zarejestrowania, i pozostawia nietknięte inne pola. Różnica polega na tym, że podając nazwę globalną, w razie potrzeby tworzy ona tabelę i dodaje odniesienie do "package.loaded". – RBerteig