Получить команду lua при вызове функции c - PullRequest
8 голосов
/ 25 мая 2010

Предположим, я зарегистрировал много разных имен функций в 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);
}

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

Ответы [ 5 ]

11 голосов
/ 25 мая 2010

Еще один способ атаковать ваш вопрос - использовать 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 сделает для вас в любом случае.

2 голосов
/ 25 мая 2010

Вы можете использовать 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.

2 голосов
/ 25 мая 2010

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

0 голосов
/ 25 мая 2010

Если вы хотите отнять все исполнения неизвестных функций, вы можете играть в игры с setmetatable и curry :

    -- 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 голосов
/ 25 мая 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...