2010-05-25 15 views
8

Lua'da çok farklı işlev adlarını C ile aynı işleve kaydettiğimi varsayalım. Şimdi, her C işlevim çağrıldığında, hangi işlev adının çağrıldığını belirlemenin bir yolu var mı? örneğinBir c işlevi çağrıldığında lua komutunu alın

:

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); 
} 

Peki şimdiye kadar işlev O'na ne adını alabilirim?

+0

Neden tüm işlevlerin aynı rutine eşlenmesini istiyorsunuz? –

+0

Bu işaretçiye sahip olan bir işlevi çağırmak istiyorum, ancak geçerli sistemde, yalnızca statik/global işlevleri arayabilirim. –

cevap

11

Sorunuzu sormanın başka bir yolu da upvalues kullanıyor. Temel olarak, işleviyle C fonksiyonlarını kayıt altına yerine 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); 
} 

Sonra getFunctionName yalındır ne yapmaya çalışıyor balık görünüyor dedi

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

- Ne çalışıyoruz başarmak? Soruya verilen runCommand işlevi, Lua'nın sizin için bir şey yapması için korkunç derecede verimsiz bir yol gibi görünüyor.

+0

Ayrıca bir 'bu' işaretçisini bir yukarı/kapanışa da yerleştirebilirsiniz. –

+0

Yükseltme değerleri kullanılırken diğer parametreleri ve bunların değişen sayısını kullanma hakkında ne düşünüyorsunuz? –

+0

@MariusK: Ne demek istediğinden emin değilim, detaylandırır mısın? – sbk

0

Maalesef, başka şeylerin yanı sıra, bu mümkün değil çünkü Lua'daki işlevlerin aslında bir ada sahip olmaları gerekmiyor. (Düşünün: (loadstring("a=1"))()loadstring döndü isimsiz işlev yerine getiriyor.) Lua_getinfo

2

Sen kullanabilirsiniz: http://pgl.yoyo.org/luai/i/lua_getinfo

Bu işe yarayabilecek:

: bir ihtar

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

yoktur isim: verilen işlev için makul bir isim. Lua'daki işlevler birinci sınıf değerler olduğundan, sabit bir adı yoktur: Bazı işlevler birden çok küresel değişkenin değeri olabilirken, diğerleri yalnızca bir tablo alanında depolanabilir. Lua_getinfo işlevi, uygun bir ad bulmak için işlevin nasıl çağrıldığını kontrol eder. Bir isim bulamazsa, ad NULL olarak ayarlanır.

2

alternatif bir çözüm bu işlevler aramaları sevk için __index metamethod uygular Lua çevre tablo için MetaTable kayıt olacaktır.

0

Eğer tüm bilinmeyen fonksiyon infaz kadar slurp istekli iseniz, setmetatable ve currying oyun oynamak mümkün olabilir: Bu örnekte

 
    -- 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") 

, sadece bilinmeyen infaz yukarı slurped ettik Küresel tablo yerine _util altında.

+0

(Lua gurus: Lütfen daha iyi bir sözdizimi veya stil değişikliği önermek için çekinmeyin, bunları dahil etmek için mutlu olacağım. Maalesef, işte motorumuza entegre olana rağmen, ne yazık ki her şeyi kullanmıyorum. – leander