Calling unknown (by name) lua function from C ++
Here's what I want to do:
1) There is a user-defined lua function that I don't know by name. Let's say that:
function f(x) return 2*x; end
2) Then the user will call the function (which was developed in step 3) from Lua, for example:
a=foo(f,3) --expecting a=6
3) C ++ function for foo:
int lua_foo(lua_State *L)
{
int nargs = lua_gettop(L);
if(nargs<2) throw "ERROR: At least two arguments i) Function ii) number must be supplied";
int type = lua_type(L, 1);
if(type!=LUA_TFUNCTION) throw "ERROR: First argument must be a function";
double arg2=lua_tonumber(L,2);
lua_pushnumber(L,arg2);
lua_pcall(L, 1, 1, 0) ; //trying to call the function f
double result=lua_tonumber(L,-1); //expecting the result to be 6
lua_pushnumber(L,result);
lua_pop(L,nargs);
return 1;
}
In C ++ code, I know that the first argument is a function and the second argument is a number. I am trying to call the first argument (function) with the second argument (number) as the argument.
source to share
If the function is constructed like this:
/* avoid `lua_` (or `luaL_`) prefix for your own functions */
static int l_foo(lua_State *L)
{
/* `lauxlib.h` contains a lot of useful helper functions, e.g. for
* argument type checking: */
luaL_checktype(L, 1, LUA_TFUNCTION);
luaL_checknumber(L, 2);
/* discard any extra arguments to `foo`; ignoring extra arguments
* is customary for Lua functions */
lua_settop(L, 2);
/* the `lua_settop()` above ensures that the two topmost elements
* of the stack are the function `f` and its argument, so
* everything is set for the `lua_call()` */
lua_call(L, 1, 1);
/* return the topmost value on the Lua stack (the result); all
* other stack values are removed by Lua automatically (but in
* this case the result is the only value on the stack as the
* `lua_call()` popped the function and the argument, and pushed
* one result) */
return 1;
}
Works as expected.
source to share
In reading the manuallua_call
, it seems to me that this is a simple stack order problem. The stack must contain, in order, the function to call, followed by the arguments in order.
When you call lua_pcall
, the stack contains a function, an argument, foo
and an argument foo
again that you push. This way the stack foo
was already correct when called and all you have to do is call lua_pcall
without any other push of the stack.
There is also a problem with you popping the result before you push the arguments into foo
from the stack, which will leave the function f
on the stack, not your result. Run the stack first, then push the result.
source to share