2010-05-25 2 views
8

Предполагается, что я регистрирую много разных имен функций в Lua для одной и той же функции в C. Теперь, каждый раз, когда вызывается моя функция C, существует ли способ определить, какое имя функции было вызвано?Получить команду lua при вызове функции c

, например:

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

Итак, как я могу получить имя того, что когда-либо функция называется это?

+0

Почему вы хотите, чтобы все функции отображались в одной и той же рутине? –

+0

Я хотел бы иметь возможность вызвать функцию, которая также имеет этот указатель, но с учетом текущей системы я могу только вызвать статические/глобальные функции. –

ответ

11

Другой способ атаковать ваш вопрос - upvalues. В принципе, вы регистрируете функции C с функцией ниже вместо 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); 
} 

Затем getFunctionName прямо вперед

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

Это говорит, что вы пытаетесь сделать кажется подозрительным - что вы пытаетесь достигать? Функция runCommand, размещенная в вопросе, выглядит как ужасно неэффективный способ сделать что-то, что Lua делает для вас в любом случае.

+0

Вы также можете поместить указатель 'this' в значение upvalue/close. –

+0

Как использовать другие параметры и их количество при использовании upvalues? –

+0

@MariusK: Я не уверен, что вы имеете в виду, можете ли вы разработать? – sbk

0

К сожалению, это невозможно - между прочим, потому что функции в Lua фактически не должны иметь имя вообще. (Подумайте: (loadstring("a=1"))() выполняет безымянную функцию, возвращенное из loadstring.)

2

Вы можете использовать lua_getinfo: http://pgl.yoyo.org/luai/i/lua_getinfo

Это может работать:

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

Существует один нюанс:

name: разумное имя для данной функции. Поскольку функции в Lua являются значениями первого класса, они не имеют фиксированного имени: некоторые функции могут быть значением нескольких глобальных переменных, а другие могут храниться только в поле таблицы. Функция lua_getinfo проверяет, как была вызвана функция, чтобы найти подходящее имя. Если он не может найти имя, тогда имя будет установлено в NULL.

2

Альтернативным решением было бы зарегистрировать metatable для таблицы окружения Lua, которая реализует метаметод __index для отправки этих вызовов функций.

0

Если вы готовы чавкать до всех неизвестных функции казни, вы можете быть в состоянии играть в игры с setmetatable и 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") 

В этом примере, я только отхлебнул до неизвестных казни под _util, а не в глобальной таблице.

+0

(Гуру Lua: не стесняйтесь предлагать лучшие синтаксические или стильные изменения, я буду рад их включить. Я не использую lua, что часто, к сожалению, несмотря на то, что оно интегрировано в наш движок на работе.) – leander

Смежные вопросы