【问题标题】:lua, call script from C with limited modules, error on string.lenlua,使用有限模块从 C 调用脚本,string.len 上的错误
【发布时间】:2020-08-24 16:38:36
【问题描述】:

我正在测试从 C.LUA 5.3.5 调用 LUA 脚本。

为了收紧使用的库,我在 C 中使用

L = luaL_newstate();
luaopen_base(L);
luaopen_string(L);
luaL_dofile(L, szFilename);
int tipo = lua_getglobal(L, "check");
int error = lua_pcall(L, 0, 0, 0);

(代码简化,没有错误处理)

这是示例 LUA 脚本:

function check()
        local buffer = "hello"
        buffer = buffer .. " world!"
        print(buffer)
        print(string.len(buffer))
end

为什么string.len会返回错误?

尝试索引一个 nil 值(全局“字符串”)

我以为 luaopen_string 会加载字符串库。

【问题讨论】:

    标签: lua


    【解决方案1】:

    luaopen_string 没有定义全局变量string:它只是将表留在堆栈上。也一样

    luaopen_string(L);
    lua_setglobal(L,"string");
    

    或者,使用luaL_requiref 而不是直接调用luaopen_string

    luaL_requiref(L,"string", luaopen_string,1);
    

    见手册最后一段section 6

    要访问这些库,C 主机程序应调用luaL_openlibs 函数,该函数会打开所有标准库。或者,宿主程序可以单独打开它们,使用 luaL_requiref 调用 ...luaopen_string(用于字符串库)...这些函数在 lualib.h 中声明。

    最后,如果您想自定义程序使用的标准库集,请编辑linit.c 并将其添加到您的项目中。更改loadedlibs 中的列表。然后拨打luaL_openlibs

    【讨论】:

    • 我调用 lua_setglobalrequire 没用。很好,我不需要luaopen_package。顺便说一句,我还必须调用 lua_setglobal(L,"base")
    • 你知道一个很好的“从 C 调用 LUA”入门吗?我用谷歌搜索了很多结果,大多数都是过时的或无用的。
    • 您无需致电lua_setglobal(L,"base")。应该是lua_setglobal(L,"_G"),但这是由luaopen_base 完成的。
    • 标准参考书是Programming in Lua
    • 请提出另一个问题。 luaopen_string + lua_setglobal 平衡堆栈。仅调用 luaopen_base 堆栈只有一个元素...我应该弹出它吗?
    【解决方案2】:

    在谈到 LUA 邮件列表后,我得到的最佳提示是查看源代码。

    luaL_openlibs 定义在 linit.c

    LUALIB_API void luaL_openlibs (lua_State *L) {
      const luaL_Reg *lib;
      /* "require" functions from 'loadedlibs' and set results to global table */
      for (lib = loadedlibs; lib->func; lib++) {
        luaL_requiref(L, lib->name, lib->func, 1);
        lua_pop(L, 1);  /* remove lib */
      }
    }
    

    所以只加载库 basestring LUA 5.3 的解决方案是

     luaL_requiref(L, "_G", luaopen_base, 1);
     lua_pop(L, 1);
     luaL_requiref(L, LUA_STRLIBNAME, luaopen_string, 1);
     lua_pop(L, 1);
    

    对于 LUA 5.4

     luaL_requiref(L, LUA_GNAME, luaopen_base, 1);
     lua_pop(L, 1);
     luaL_requiref(L, LUA_STRLIBNAME, luaopen_string, 1);
     lua_pop(L, 1);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-22
      • 1970-01-01
      • 2017-05-07
      • 1970-01-01
      • 2011-03-24
      • 2021-03-25
      • 2018-08-31
      • 2014-08-06
      相关资源
      最近更新 更多