Supposed I register many different function names in Lua to the same function in C. Now, everytime my C function is called, is there a way to determine which function name was invoked?
for example:
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)
开发者_Python百科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);
}
So, how do I get the name of what ever function called it?
Another way to attack your question is by using upvalues. Basically, you register the C functions with the function below instead of 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);
}
Then, getFunctionName is straight forward
const char* getFunctionName(lua_State* L)
{
return lua_tostring(L, lua_upvalueindex(1));
}
That said, what you trying to do seems fishy - what are you trying to achieve? The runCommand
function posted in the question looks like a horribly inefficient way to do something that Lua does for you anyway.
You can use lua_getinfo : http://pgl.yoyo.org/luai/i/lua_getinfo
This might work:
const char* lua_getcurrentfunction(lua_State* L) {
lua_Debug ar;
lua_getstack(L, 1, &ar);
lua_getinfo(L, "f", &ar);
return ar.name;
}
There is one caveat:
name: a reasonable name for the given function. Because functions in Lua are first-class values, they do not have a fixed name: some functions may be the value of multiple global variables, while others may be stored only in a table field. The lua_getinfo function checks how the function was called to find a suitable name. If it cannot find a name, then name is set to NULL.
An alternative solution would be to register a metatable for the Lua environment table that implements the __index
metamethod for dispatching these functions calls.
Unfortunately, that's not possible - among other things, because functions in Lua don't actually have to have a name at all. (Consider: (loadstring("a=1"))()
is executing a nameless function returned from loadstring
.)
If you're willing to slurp up all unknown function executions, you may be able to play games with setmetatable and 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" )
In this example, I've only slurped up unknown executions under _util
rather than in the global table.
精彩评论