如何在luaapi中使用'debug.getinfo(f).nparams'?
我了解到,在Lua中使用如何在luaapi中使用'debug.getinfo(f).nparams'?,lua,Lua,我了解到,在Lua中使用debug.getinfo(f).nparams可以找出函数需要多少参数 在使用Lua_pcall()调用函数之前,有人能教我如何在Lua C API中执行此操作吗 下面是我调用Lua函数的示例代码 void doFunction(lua_State *L, int argc, t_atom *argv) { lua_getglobal(L, "require"); lua_pushstring(L, "foo");
debug.getinfo(f).nparams
可以找出函数需要多少参数
在使用Lua_pcall()
调用函数之前,有人能教我如何在Lua C API中执行此操作吗
下面是我调用Lua函数的示例代码
void doFunction(lua_State *L, int argc, t_atom *argv)
{
lua_getglobal(L, "require");
lua_pushstring(L, "foo"); //require("foo")
if (lua_pcall(L, 1, LUA_MULTRET, 0))
{
error("error: %s", lua_tostring(L, -1));
lua_pop(L, 1);
return;
}
int top = lua_gettop(L);
lua_getfield(L, -1, "test"); //find foo.test() function
if (lua_type(L, -1) != LUA_TFUNCTION)
{
lua_pop(L, 2);
return;
}
lua_newtable(L);
for (int i = 0; i < argc; ++i) //convert array to lua table
{
lua_pushinteger(L, static_cast<lua_Integer>(i + 1));
if (argv[i].a_type == A_FLOAT)
lua_pushnumber(L, static_cast<lua_Number>(argv[i].a_w.w_float));
else if (argv[i].a_type == A_SYMBOL)
lua_pushstring(L, argv[i].a_w.w_symbol->s_name);
lua_settable(L, -3);
}
if (lua_pcall(L, 1, LUA_MULTRET, 0)) //call foo.test() function
{
error("error: %s", lua_tostring(L, -1));
lua_pop(L, 1);
return;
}
if (lua_gettop(L) - top)
{
//do something with the returned value
}
lua_pop(L, 1);
}
然而,我不知道应该把这些行放在哪里才能使我的代码正常工作
谁能教我怎么做
添加: 我想通过传递表或参数值来调用函数,具体取决于函数所需的参数数量。例如,如果函数需要一个参数,我将向函数传递一个表。但是如果函数需要多个参数,我希望将这些值作为多个参数传递。这就是为什么我需要使用
debug.getinfo(f).nparams
来描述如何获取有关函数的信息:
要获取有关函数的信息,请将其推送到堆栈上,并用字符“>”启动what字符串。(在这种情况下,lua_getinfo从堆栈顶部弹出函数。)例如,要知道函数f是在哪一行定义的,可以编写以下代码:
lua_Debug ar;
lua_getglobal(L, "f"); /* get global 'f' */
lua_getinfo(L, ">S", &ar);
printf("%d\n", ar.linedefined);
因此,您唯一缺少的就是将要检查的函数值推送到Lua堆栈的顶部
为了给您一些可玩的东西,下面是一个C函数的实现,该函数调用作为第一个参数传递的函数,其余参数作为数组或单个参数传递,具体取决于预期参数的数量:
/* build instructions for `args.c` on Ubuntu Linux:
* `gcc -Wall -I/usr/include/lua5.2 -fpic -shared -o args.so args.c`
*/
#include <lua.h>
#include <lauxlib.h>
/* copies a Lua stack interval into an array */
static void push_pack(lua_State* L, int first, int last) {
int i;
first = lua_absindex(L, first);
last = lua_absindex(L, last);
lua_createtable(L, last > first ? last - first : 0, 0);
for (i = first; i <= last; ++i) {
lua_pushvalue(L, i);
lua_rawseti(L, -2, i-first+1);
}
}
static int args(lua_State* L) {
lua_Debug ar;
/* first argument must be a function to call, rest are additional
* args for this function */
luaL_checktype(L, 1, LUA_TFUNCTION);
/* query number of expected arguments */
lua_pushvalue(L, 1);
lua_getinfo(L, ">u", &ar);
if (ar.nparams > 1 || ar.isvararg) { /* pass as multiple args */
lua_call(L, lua_gettop(L)-1, LUA_MULTRET);
return lua_gettop(L);
} else { /* create array and pass it as single arg */
int top = lua_gettop(L);
lua_pushvalue(L, 1); /* push function first */
push_pack(L, 2, top); /* then argument array */
lua_call(L, 1, LUA_MULTRET);
return lua_gettop(L) - top;
}
}
int luaopen_args(lua_State* L) {
lua_pushcfunction(L, args);
return 1;
}
@路德,非常感谢你。请看我编辑过的帖子。“但是,我不知道应该把这些行放在哪里才能让我的代码正常工作。”为了让代码正常工作,应该把它们放在哪里?现在还不清楚您的代码试图实现什么,以及为什么需要知道函数的参数数量。函数通过传递一个包含值的表来调用函数。问一个关于这里应该适合的参数数量的问题在哪里?你是想把数组作为实际参数而不是表来传递吗?@Nicolas是的,我是想把数组作为实际参数而不是表来传递。如果你想悬赏你的问题,要求答案提供更多细节,最好把你所有的问题都放在你的问题中,而不是强迫别人阅读评论,试图找出你真正想要的是什么。尽量说得清楚些。@NicolBolas我刚才说了。谢谢
/* build instructions for `args.c` on Ubuntu Linux:
* `gcc -Wall -I/usr/include/lua5.2 -fpic -shared -o args.so args.c`
*/
#include <lua.h>
#include <lauxlib.h>
/* copies a Lua stack interval into an array */
static void push_pack(lua_State* L, int first, int last) {
int i;
first = lua_absindex(L, first);
last = lua_absindex(L, last);
lua_createtable(L, last > first ? last - first : 0, 0);
for (i = first; i <= last; ++i) {
lua_pushvalue(L, i);
lua_rawseti(L, -2, i-first+1);
}
}
static int args(lua_State* L) {
lua_Debug ar;
/* first argument must be a function to call, rest are additional
* args for this function */
luaL_checktype(L, 1, LUA_TFUNCTION);
/* query number of expected arguments */
lua_pushvalue(L, 1);
lua_getinfo(L, ">u", &ar);
if (ar.nparams > 1 || ar.isvararg) { /* pass as multiple args */
lua_call(L, lua_gettop(L)-1, LUA_MULTRET);
return lua_gettop(L);
} else { /* create array and pass it as single arg */
int top = lua_gettop(L);
lua_pushvalue(L, 1); /* push function first */
push_pack(L, 2, top); /* then argument array */
lua_call(L, 1, LUA_MULTRET);
return lua_gettop(L) - top;
}
}
int luaopen_args(lua_State* L) {
lua_pushcfunction(L, args);
return 1;
}
#!/usr/bin/lua5.2
local args = require("args")
local function f(x, ...)
print(">", x, ...)
return 5, 6
end
local function g(x)
print(">", x)
for i,v in ipairs(x) do
print("", i, v)
end
return 7, 8
end
local function h(x, y)
print(">", x, y)
return 9, 10
end
print(args(f, 1, 2, 3))
print(args(g, 1, 2, 3))
print(args(h, 1, 2, 3))
print(args(print, 1, 2, 3))