如何处理作为参数传递给LUAC函数的表?
我将用C语言实现一个函数,它将由Lua脚本调用 这个函数应该接收一个lua表作为参数,所以我应该读取表中的字段。我尝试执行下面的操作,但是我的函数在运行时崩溃了。有人能帮我找到问题吗如何处理作为参数传递给LUAC函数的表?,c,lua,lua-table,C,Lua,Lua Table,我将用C语言实现一个函数,它将由Lua脚本调用 这个函数应该接收一个lua表作为参数,所以我应该读取表中的字段。我尝试执行下面的操作,但是我的函数在运行时崩溃了。有人能帮我找到问题吗 /* function findImage(options) imagePath = options.imagePath fuzzy = options.fuzzy ignoreColor = options.ignoreColor; end Call Example:
/*
function findImage(options)
imagePath = options.imagePath
fuzzy = options.fuzzy
ignoreColor = options.ignoreColor;
end
Call Example:
findImage {imagePath="/var/image.png", fuzzy=0.5, ignoreColor=0xffffff}
*/
// implement the function by C language
static int findImgProxy(lua_State *L)
{
luaL_checktype(L, 1, LUA_TTABLE);
lua_getfield(L, -1, "imagePath");
if (!lua_isstring(L, -1)) {
error();
}
const char * imagePath = lua_tostring(L, -2);
lua_pop(L, 1);
lua_getfield(L, -1, "fuzzy");
if (!lua_isnumber(L, -1)) {
error();
}
float fuzzy = lua_tonumber(L, -2);
lua_getfield(L, -1, "ignoreColor");
if (!lua_isnumber(L, -2)) {
error();
}
float ignoreColor = lua_tonumber(L, -2);
...
return 1;
}
将表从C返回到Lua怎么样:
在使用Lua C API时,熟悉虚拟堆栈非常重要——所有重要的语言边界交互都发生在虚拟堆栈中。查看您的代码片段,看起来您并没有将数据正确地封送到C 编写lua C函数时,基本上需要做3件事:
- 将输入的lua数据转换为可以在C中使用的数据
- 执行处理或函数需要执行的任何操作
- 转换并将输出结果(如果有)返回给lua
findImgProxy
应该是这样的:
static int findImgProxy(lua_State *L)
{
// discard any extra arguments passed in
lua_settop(L, 1);
luaL_checktype(L, 1, LUA_TTABLE);
// Now to get the data out of the table
// 'unpack' the table by putting the values onto
// the stack first. Then convert those stack values
// into an appropriate C type.
lua_getfield(L, 1, "imagePath");
lua_getfield(L, 1, "fuzzy");
lua_getfield(L, 1, "ignoreColor");
// stack now has following:
// 1 = {imagePath="/var/image.png", fuzzy=0.5, ignoreColor=0xffffff}
// -3 = "/var/image.png"
// -2 = 0.5
// -1 = 0xffffff
const char *imagePath = luaL_checkstring(L, -3);
double fuzzy = luaL_checknumber(L, -2);
int ignoreColor = luaL_checkint(L, -1);
// we can pop fuzzy and ignoreColor off the stack
// since we got them by value
lua_pop(L, 2);
// do function processing
// ...
return 1;
}
请注意,我们必须在堆栈上保留imagePath
,因为我们将const char*
保存在堆栈上。弹出该字符串将使*imagePath
无效,因为lua可能会收集它
或者,您可以将luaL\u checkstring
返回的字符串复制到另一个缓冲区中。在本例中,弹出字符串是可以的,因为我们不再指向lua拥有的内部缓冲区
编辑:如果表中的某些键是可选的,则可以使用luaL\u opt*
函数并提供默认值。例如,如果fuzzy
和ignoreColor
是可选的:
// ...
const char *imagePath = luaL_checkstring(L, -3);
double fuzzy = luaL_optnumber(L, -2, 0.0); // defaults to 0.0 if no fuzzy
int ignoreColor = luaL_optint(L, -1, 0); // defaults to 0 if no ignoreColor
// ...
因此,如果调用代码为键提供了一个无意义的值,这仍然会引发错误。OTOH,如果不存在,则值为
nil
,并使用提供的默认值。有什么问题吗?你期望它做什么?它在做什么不正确?我想读C函数中的lua表,但它崩溃了,我仍在寻找问题。所以我希望有人能帮我检查我使用的方法是否正确。@greatwolf非常感谢,我从来没有得到过像你这样清晰而有用的答案。通常我理解。但我有另一个问题,我应该从C函数返回一个表到lua,但是我的代码(上面添加的)不起作用,你能看一下吗?非常感谢。如果参数表的键号没有固定,该表可能是{imagePath=“/var/q.png”}或者可能是{imagePath=“/var/q.png”,fuzzy=1.0},或者可能是{imagePath=“/var/q.png”,ignoreColor=0xffffff}。我如何获取值?@Suge如果某些键是可选的,您可以使用luaL\u opt*
函数获取它们。@Suge我已经为此添加了一个示例。非常感谢,我知道了。你能看一下上面我用来从C函数返回表的代码吗?
// ...
const char *imagePath = luaL_checkstring(L, -3);
double fuzzy = luaL_optnumber(L, -2, 0.0); // defaults to 0.0 if no fuzzy
int ignoreColor = luaL_optint(L, -1, 0); // defaults to 0 if no ignoreColor
// ...