Reputation: 1025
Here is what I want to do:
1) There is a lua function defined by the user, which I dont know by name. Say it is:
function f(x) return 2*x; end
2) The user will then call a function (that is designed in step 3) from Lua say like:
a=foo(f,3) --expecting a=6
3) The C++ function for foo is:
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 the C++ code, I know the first argument is a function and second argument is a number. I am trying to call the first argument (the function) with the second argument (the number) as its arg.
Upvotes: 3
Views: 848
Reputation: 1025
If the function is designed as below:
/* 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;
}
It works as expected.
Upvotes: 3
Reputation: 409136
By reading the lua_call
manual it's seems to me to be a simple stack order problem. The stack should contain, in order, the function to call followed by the arguments in order.
When you call lua_pcall
the stack contains the function, the argument to foo
and the argument to foo
again that you push. So the stack on the call of foo
was already correct, and all you have to do is call lua_pcall
without any other stack pushing.
There also the problem that you push the result before you pop the arguments to foo
from the stack, which will leave the function f
on the stack and not your result. Pop the stack first then push the result.
Upvotes: 2