如何使用作为参数传递给Lua C函数的表?
2013-9-6 22:19:50
收藏:0
阅读:132
评论:1
我将要用C语言实现一个函数,并且这个函数将会被Lua脚本调用。
这个函数应该以一个Lua表作为参数,所以我应该读取表中的字段。我试图像下面一样做,但是当我运行它时,我的函数会崩溃。有人能帮我找到问题吗?
/*
function findImage(options)
imagePath = options.imagePath
fuzzy = options.fuzzy
ignoreColor = options.ignoreColor;
end
呼叫範例:
findImage {imagePath="/var/image.png", fuzzy=0.5, ignoreColor=0xffffff}
*/
// 用C语言实现函数
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:
struct Point {
int x, y;
}
typedef Point Point;
static int returnImageProxy(lua_State *L)
{
Point points[3] = {{11, 12}, {21, 22}, {31, 32}};
lua_newtable(L);
for (int i = 0; i 3; i++) {
lua_newtable(L);
lua_pushnumber(L, points[i].x);
lua_rawseti(L, -2, 0);
lua_pushnumber(L, points[i].y);
lua_rawseti(L, -2, 1);
lua_settable(L,-3);
}
return 1; // 我希望返回一个Lua表格,比如: {{11, 12}, {21, 22}, {31, 32}}
}
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
在Lua C API中工作时,熟悉使用虚拟栈很重要——所有重要的语言边界交互都发生在那里。看看你的代码片段,似乎你没有正确地将数据编组到C中。
编写Lua C函数时,你基本上需要完成三件事:
以下是
findImgProxy应该是什么样子的示例:static int findImgProxy(lua_State *L) { // 抛弃传入的任何额外参数 lua_settop(L, 1); luaL_checktype(L, 1, LUA_TTABLE); // 现在从表中获取数据 // 通过将值放入栈中 '解包' 表,然后将这些栈值转换为适当的C类型。 lua_getfield(L, 1, "imagePath"); lua_getfield(L, 1, "fuzzy"); lua_getfield(L, 1, "ignoreColor"); // 现在栈中有以下内容: // 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); // 我们可以弹出模糊度和忽略颜色从栈上, // 因为我们已经用值取到了它们 lua_pop(L, 2); // 进行函数处理 // ... return 1; }请注意,我们必须保留
imagePath在堆栈上,因为我们拥有对其的const char *。弹出该字符串会使* imagePath无效,因为Lua可能会收集它。或者,您可以将
luaL_checkstring返回的字符串复制到另一个缓冲区中。在这种情况下,弹出字符串是可以的,因为我们不再指向Lua拥有的内部缓冲区。编辑: 如果表中的某些键是可选的,则可以改用
luaL_opt*函数并提供默认值。例如,如果fuzzy和ignoreColor是可选的:// ... const char *imagePath = luaL_checkstring(L, -3); double fuzzy = luaL_optnumber(L, -2, 0.0); // 如果缺少fuzzy,则默认为0.0 int ignoreColor = luaL_optint(L, -1, 0); // 如果缺少ignoreColor,则默认为0 // ...因此,如果调用代码为键提供了无意义的值,则仍会引发错误。另一方面,如果缺少它,则值为
nil,并使用提供的默认值。