【问题标题】:Am I right to read a nested lua table as argument from C function?我是否可以从 C 函数中读取嵌套的 lua 表作为参数?
【发布时间】:2013-09-06 18:18:35
【问题描述】:

我打算用 C 语言实现一个函数,它会被 Lua 脚本调用。

这个函数应该接收一个 lua 表(甚至包含一个数组)作为参数,所以我应该读取表中的字段。我尝试像下面那样做,但是当我运行它时我的函数崩溃了。谁能帮我找到问题?

/* function findImage(options) imagePath = options.imagePath fuzzy = options.fuzzy ignoreColors = options.ignoreColor; ... end Call Example: findImage { imagePath="/var/image.png", fuzzy=0.5, ignoreColors={ 0xffffff, 0x0000ff, 0x2b2b2b } } */ static int findImgProxy(lua_State *L) { lua_settop(L, 1); luaL_checktype(L, 1, LUA_TTABLE); lua_getfield(L, -1, "imagePath"); lua_getfield(L, -2, "fuzzy"); lua_getfield(L, -3, "ignoreColors"); const char *imagePath = luaL_checkstring(L, -3); double fuzzy = luaL_optint(L, -2, -1); int count = lua_len(L, -1); // how to get the member count of ignoreColor array int colors[count]; for (int i=0; i count; i++) { lua_rawgeti(L, 4, i); colors[i] = luaL_checkinteger(L, -1); lua_pop(L, 1); } lua_pop(L, 2); ... return 1; }

【问题讨论】:

    标签: c++ c lua lua-table


    【解决方案1】:

    lua_len 不返回任何内容,它只是将长度推入堆栈。使用此 sn-p 获取表长度:

    lua_len(L, -1);
    int count = luaL_checkinteger(L, -1);
    lua_pop(L, 1);
    

    【讨论】:

    • 我试过使用int count = lua_rawlen,这行得通。对吗?
    • 是的,它也有效。与lua_rawlen 不同,lua_len 必须 将其结果压入堆栈,因为它可能会触发__len 元方法,该方法可能返回从niluserdata 的任何内容。
    • 感谢您的帮助。
    【解决方案2】:
    int count  = lua_len(L, -1); // how to get the member count of ignoreColor array
    
    int colors[count];
    for (int i=0; i count; i++)
    {
        colors[i] = luaL_checkinteger(L, -1-i);
    }
    

    此代码段看起来不正确(不要介意循环中缺少的比较运算符)。获取表格长度的正确函数是lua_objlen。看起来您正试图从“ignoreColor”中取出数字,但您没有先将它们放在堆栈中。结果luaL_checkinteger(L, -1-i); 最终访问了堆栈上的错误索引

    你可能想要更接近这个的东西,例如:

    int count  = lua_objlen(L, -1);
    std::vector<int> colors(count);
    for (int i = 0; i < count; lua_pop(L, 1))
    {
      lua_rawgeti(L, 4, ++i);
      colors.push_back( luaL_checkinteger(L, -1) );
    }
    

    如果您使用的是 Lua 5.2,请将 lua_objlen 替换为:

    int count  = lua_rawlen(L, -1);
    

    如果要从表中移动大量元素,请确保堆栈上有足够的空间。例如。 lua_checkstack

    【讨论】:

    • lua_len 是在 Lua 5.2 中获取表长度的正确函数,尽管它执行了不必要的元表检查。
    • @peterm arrg 他们不得不去更改 api :( 太烦人了
    • @greatwolf,感谢您的帮助。我已经编辑了我上面的代码,你能看一下吗?
    • @Suge 请注意,可变长度数组是 gcc 的扩展,这就是我在示例中使用 vector 的原因。
    猜你喜欢
    • 1970-01-01
    • 2015-01-18
    • 2013-06-03
    • 2021-03-30
    • 1970-01-01
    • 2016-07-27
    • 2016-07-01
    • 2021-10-09
    • 1970-01-01
    相关资源
    最近更新 更多