2010-05-25 15 views
8

Przypuszczam, że rejestruję wiele różnych nazw funkcji w Lua do tej samej funkcji w C. Teraz, za każdym razem, gdy wywoływana jest moja funkcja C, czy istnieje sposób na określenie, która nazwa funkcji została wywołana?Uzyskaj polecenie lua, gdy funkcja c nazywa się

na przykład:

int runCommand(lua_State *lua) 
{ 
    const char *name = // getFunctionName(lua) ? how would I do this part 
    for(int i = 0; i < functions.size; i++) 
    if(functions[i].name == name) 
     functions[i].Call() 
} 

int main() 
{ 
    ... 

    lua_register(lua, "delay", runCommand); 
    lua_register(lua, "execute", runCommand); 
    lua_register(lua, "loadPlugin", runCommand); 
    lua_register(lua, "loadModule", runCommand); 
    lua_register(lua, "delay", runCommand); 
} 

Tak, jak mogę uzyskać nazwę funkcji, co kiedykolwiek nazwał go?

+0

Dlaczego wszystkie funkcje mają być odwzorowywane na tę samą procedurę? –

+0

Chciałbym móc wywołać funkcję, która ma również ten wskaźnik, ale biorąc pod uwagę obecny system, mogę tylko wywoływać funkcje statyczne/globalne. –

Odpowiedz

11

Innym sposobem na zaatakowanie pytania jest użycie upvalues. Zasadniczo, można zarejestrować funkcji C z funkcją poniżej zamiast lua_register:

void my_lua_register(lua_State *L, const char *name, lua_CFunction f) 
{ 
     lua_pushstring(L, name); 
     lua_pushcclosure(L, f, 1); 
     lua_setglobal(L, name); 
} 

Następnie getFunctionName jest prosta

const char* getFunctionName(lua_State* L) 
{ 
    return lua_tostring(L, lua_upvalueindex(1)); 
} 

Powiedział, że to, co staramy się robić wydaje podejrzany - Co ty próbujesz osiągnąć? Funkcja runCommand umieszczona w pytaniu wygląda jak strasznie nieefektywny sposób, aby zrobić coś, co i Lua robi dla ciebie.

+0

Możesz również umieścić wskaźnik "this" w wartościowości/zamknięciu. –

+0

Co z używaniem innych parametrów i ich różną liczbą przy korzystaniu z upvalues? –

+0

@MariusK: Nie jestem pewien, co masz na myśli, możesz rozwinąć? – sbk

0

Niestety, nie jest to możliwe - między innymi dlatego, że funkcje w Lua wcale nie muszą mieć nazwy. (Rozważyć: (loadstring("a=1"))() realizuje bezimienny funkcji zwracany z loadstring.)

2

Można użyć lua_getinfo: http://pgl.yoyo.org/luai/i/lua_getinfo

Może to działa:

const char* lua_getcurrentfunction(lua_State* L) { 
    lua_Debug ar; 
    lua_getstack(L, 1, &ar); 
    lua_getinfo(L, "f", &ar); 
    return ar.name; 
} 

Jest jedno zastrzeżenie:

nazwa: rozsądna nazwa dla danej funkcji. Ponieważ funkcje w Lua są wartościami pierwszej klasy, nie mają one stałej nazwy: niektóre funkcje mogą być wartością wielu zmiennych globalnych, podczas gdy inne mogą być przechowywane tylko w polu tabeli. Funkcja lua_getinfo sprawdza, w jaki sposób funkcja została wywołana, aby znaleźć odpowiednią nazwę. Jeśli nie może znaleźć nazwy, wówczas jej nazwa zostanie ustawiona na NULL.

2

Alternatywnym rozwiązaniem byłoby, aby zarejestrować metatable dla tabeli środowiska Lua, który implementuje __index metamethod za dostarczenie tych wywołań funkcji.

0

Jeśli jesteś gotów do slurp się wszystkie nieznanych egzekucje funkcyjne, może być w stanie grać w gry z setmetatable i currying:

 
    -- This function would not be in lua in your example, 
    -- you'd be doing lua_register(lua, "runCommandNamed", runCommandNamed) 
    -- and writing a runCommandNamed in C. 
    function runCommandNamed(cmd, ...) 
     print("running command", cmd, "with arguments", ...) 
    end 

    -- The rest would be somewhere in lua-land: 
    local utilMetaTable = { 
     __index = function (t, key) 
      return function(...) -- mmm, curry 
       runCommandNamed(key, ...) 
      end 
     end 
    } 

    _util = {} 
    setmetatable(_util, utilMetaTable) 

    -- prints "running command CommandOne  with arguments arg1 arg2 arg3" 
    _util.CommandOne("arg1", "arg2", "arg3") 

    -- prints "running command CommandTwo  with arguments argA argB" 
    _util.CommandTwo("argA", "argB") 

W tym przykładzie, mam tylko slurped nieznanych egzekucje pod _util zamiast w tabeli globalnej.

+0

(Lua guru: możesz zaproponować lepsze zmiany w składni lub stylach, chętnie je wykorzystam, niestety nie używam lua, niestety, pomimo tego, że zintegrowałam ją z naszym silnikiem w pracy.) – leander

Powiązane problemy