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

我想做的事情如下:

1)有一个用户定义的 Lua 函数,我不知道它的名称。假设它是:

function f(x) return 2*x; end

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

a=foo(f,3) --期望 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++ 代码中,我知道第一个参数是一个函数,第二个参数是一个数字。我试图用第二个参数作为它的参数来调用第一个参数(函数)。

点赞
用户440558
用户440558

通过阅读 lua_call 手册,我认为这只是一个简单的堆栈顺序问题。堆栈应该按顺序包含要调用的函数,然后是相应的参数。

当你调用 lua_pcall 时,堆栈包含函数、foo 的参数和你推入的 foo 参数,所以在调用 foo 时,堆栈已经是正确的了,只需要调用 lua_pcall,不需要推入其他堆栈。

此外,还有一个问题,你在弹出作为 foo 参数的参数之前推入了结果,这将使函数 f 保留在堆栈中,而不是你的结果。先弹出堆栈然后再推入结果。


2015-05-27 07:05:00
用户1521241
用户1521241

如果函数设计如下:

/* 避免为您自己的函数添加 `lua_`(或`luaL_`)前缀 */
static int l_foo(lua_State *L)
{
    /* `lauxlib.h` 包含很多有用的辅助函数,例如用于
     * 参数类型检查的:*/
    luaL_checktype(L, 1, LUA_TFUNCTION);
    luaL_checknumber(L, 2);
    /* 丢弃 `foo` 的任何额外参数;忽略额外参数
     * 是 Lua 函数的惯例 */
    lua_settop(L, 2);
    /* 上面的 `lua_settop()` 确保栈中最上面的两个元素
     * 是函数 `f` 和其参数,因此一切都为 `lua_call()` 准备好了 */
    lua_call(L, 1, 1);
    /* 返回 Lua 栈上最上面的值(结果);所有
     * 其他栈值都将由 Lua 自动删除(但在
     * 这种情况下,由于 `lua_call()` 弹出了函数和参数,并推
     * 了一个结果,因此结果是堆栈上唯一的值) */
    return 1;
}

它会按预期工作。

2015-05-27 08:36:07