从 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;
}
它按预期工作。
这是我想要做的:
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;
}
它按预期工作。