当调用一个C函数时,获取lua命令。

假设我在 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);
}

那么,如何获取调用它的任何函数的名称?

原文链接 https://stackoverflow.com/questions/2907221

点赞
stackoverflow用户148870
stackoverflow用户148870

很遗憾,这是不可能的 - 其中一个原因是,Lua 中的函数实际上不必拥有名称。 (考虑:(loadstring(“a=1”)()) 正在执行从 loadstring 返回的一个无名函数。)

2010-05-25 18:19:26
stackoverflow用户30470
stackoverflow用户30470

你可以使用 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。

2010-05-25 18:33:29
stackoverflow用户1491
stackoverflow用户1491

另一种解决方案是为 Lua 环境表注册元表,该元表实现了 __index 元方法,用于调度这些函数调用。

2010-05-25 18:50:20
stackoverflow用户80074
stackoverflow用户80074

如果你想接受 所有 未知函数调用,你可能可以使用 setmetatablecurrying 玩游戏:

    -- 在你的例子中该函数不会在 lua 中,
    -- 你会使用 lua_register( lua, "runCommandNamed", runCommandNamed )
    -- 并且在 C 语言中编写一个 runCommandNamed 函数。
    function runCommandNamed( cmd, ... )
        print( "running command", cmd, "with arguments", ... )
    end

    -- 其余代码都在 lua 中:
    local utilMetaTable = {
        __index = function ( t, key )
            return function( ... ) -- 嗯嗯,柯里化
                runCommandNamed( key, ... )
            end
        end
    }

    _util = {}
    setmetatable( _util, utilMetaTable )

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

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

在这个例子中,我只对 _util 中的未知函数调用进行了接受,而没有在全局表中进行。

2010-05-25 19:00:32
stackoverflow用户169828
stackoverflow用户169828

另一种攻击问题的方法是使用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);
}

然后,获取函数名称就很简单了:

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

尽管如此,您试图做的事情似乎有些可疑 - 您想要实现什么?问题中发布的runCommand函数看起来像是一种极为低效的方法,而Lua能够为您执行该操作。

2010-05-25 19:47:29