lua,使用受限模块从C调用脚本时string.len出现错误

我正在测试从C调用Lua脚本。LUA版本号是5.3.5。

为了限制使用的库,在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 函数会返回错误?

attempt to index a nil value (global 'string')

我以为 luaopen_string 会加载string库的。

点赞
用户107090
用户107090

luaopen_string 不会定义全局变量 string,它只是将表格留在栈上。因此可以这么做:

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

或者通过使用 luaL_requiref 来替代直接调用 luaopen_string

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

请参阅手册中的 第6节 的最后一段:

要访问这些库,C 语言宿主程序应该调用函数 luaL_openlibs,这个函数打开所有标准库。或者,宿主程序可以使用 luaL_requiref 分别打开它们,通过调用 ... luaopen_string 函数(string 库)... 这些函数在 lualib.h 中声明。

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

2020-05-09 12:21:02
用户471232
用户471232

在 LUA 邮件列表上讨论后,我得到的最好提示是查看源代码。

luaL_openlibslinit.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);
2020-05-11 22:25:08