从 C++ 调用未知(按名称)lua 函数

Calling unknown (by name) lua function from C++

这是我想要做的:

1) 有一个用户定义的lua函数,我不知道名字。说是:

function f(x) return 2*x; end

2) 然后用户将从 Lua 调用函数(在步骤 3 中设计),例如:

a=foo(f,3) --expecting a=6

3) foo 的 C++ 函数是:

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;
}

在C++代码中,我知道第一个参数是一个函数,第二个参数是一个数字。我正在尝试用第二个参数(数字)作为参数调用第一个参数(函数)。

reading the lua_call manual 在我看来这是一个简单的堆栈顺序问题。堆栈应按顺序包含要调用的函数,然后按顺序包含参数。

当您调用 lua_pcall 时,堆栈包含函数、foo 的参数 foo 的参数 再次你推。所以调用 foo 的堆栈已经正确,你所要做的就是调用 lua_pcall 而无需任何其他堆栈推送。


还有一个问题是,您在 之前将结果推送到 ,然后将参数从堆栈中弹出到 foo,这将使函数 f 保持打开状态堆栈而不是你的结果。先出栈然后压入结果。

如果函数设计如下:

/* 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;
}

它按预期工作。