3

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.

2
  • So what exactly is the problem? Compiler error? Runtime error? Commented May 27, 2015 at 7:00
  • None, the result is always 0 rather than being 6 Commented May 27, 2015 at 7:14

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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.

2 Comments

I modified the code as follows: int nargs = lua_gettop(L); int type = lua_type(L, 2); double arg2=lua_tonumber(L,1); lua_pcall(L, 1, 1, 0) ; double result=lua_tonumber(L,-1); lua_pop(L,nargs); lua_pushnumber(L,result); return 1; So now the function is on top of the stack and it still does not work.
As told, check the manual. It says the stack must be: first the function, then n args. After lua_pcall(), the stack contains only the results, so you shouldn't call lua_pop(L, nargs).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.