Предполагаемый я регистрирую много различных имен функций в Lua к той же функции в C. Теперь, каждый раз моя функция 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);
}
Так, как я получаю название того, что когда-нибудь функционирует, назвал его?
Другой способ ответить на ваш вопрос - использовать 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 все равно делает за вас.
Вы можете использовать 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 проверяет, как функция была вызвана, чтобы найти подходящее имя. Если не может найти имя, тогда name устанавливается в NULL.
Если вы хотите пропустить все выполнение неизвестных функций, вы можете играть в игры с setmetatable и каррированием :
-- 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" )
In В этом примере я только пропустил неизвестные исполнения в _util
, а не в глобальной таблице.
Альтернативным решением было бы зарегистрировать метатаблицу для таблицы среды Lua, которая реализует метаметод __ index
для диспетчеризации вызовов этих функций.
К сожалению, это невозможно - среди прочего, потому что функции в Lua на самом деле вообще не должны иметь имя. (Рассмотрим: (loadstring("a=1"))()
выполняет безымянный вызов функции, возвращаемой из loadstring
.)