问题是,“require”关键字会清除同一文件中定义的所有全局变量。
我正在用 C++ 开发一个项目。我使用 lua 5.3。 lua脚本风格是:
1 所有lua代码包含1个公共(public)库文件,以及若干个小文件,每个文件作为一个函数。
2 程序启动时,lua公共(public)库被编译执行,将其全局变量保持在lua状态。然后编译小文件不执行。
3 当程序执行到某个点时,会调用相关的lua小文件(就像我说的,每个小文件都是一个函数)。公共(public)库中定义的全局函数和变量将在小lua文件中使用。这就是为什么我在程序启动时编译并执行公共(public)库的原因。
4 我很确定我只使用了 1 个 lua_State。
它运行良好,直到我决定将公共(public)库拆分为多个文件,并在主文件中使用“require”。程序启动时,会编译并执行主文件。
没有更改任何代码,只需添加“require”即可。奇怪的事情发生了:所有的全局变量和全局函数都丢失了。当在小的 lua 文件中调用全局函数时,会引发“调用 nil 值”错误。
然后我做了一个实验,我删除了主库文件中的所有“require”行,结果发现主库中定义的全局函数工作得很好。然后我需要一个空文件“simple.lua”,主库中定义的全局函数丢失,无法从小 lua 文件调用。
这个怎么解释? “require”关键字如何清除同一文件中定义的所有全局变量?
在lua库中:
require("simple")
function foo()
return 1+1
end
在lua小文件中
return foo()
结果:尝试调用一个 nil 值(全局 'foo')
删除“require”后,lua库:
function foo()
return 1+1
end
结果:没有错误发生,返回2
C++ 端代码:
lua公共(public)库编译执行:
int code = luaL_loadbuffer(L, s, strlen(s), "commonlib");
if(code != 0) {
std::string error = lua_tostring(L, -1);
lua_pop(L, 1);
return error;
}
code = lua_pcall(L, 0, 0, 0);
if(code > 0)
{
std::string ret = lua_tostring(L, -1);
lua_pop(L, 1);
return ret;
}
else
return ""; //empty string means no error
lua小函数文件编译:
int code = luaL_loadbuffer(L, s, strlen(s), "RULE1");
if(code != 0) {
std::string error = lua_tostring(L, -1);
lua_pop(L, 1);
return error;
}
else
{
return ""; //return empty means no error
}
两个代码中的 L 是相同的 lua 状态(或者当“require”被移除时它不会工作)。编译后,栈顶的小文件函数以引用变量“ref”保存在全局寄存器中。 调用lua小文件时,ref入栈,使用lua_pcall,没什么特别的。
最佳答案
自己解决了这个问题。 由于重复的复制/粘贴,lua vm 是在之后第二次创建的。这相当令人困惑,因为如果没有“要求”,一切都很好。这完全是巧合。
我从中学到的是:始终仔细检查复制/粘贴代码。
关于c++ - 在 lua 中使用 require 后全局变量丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56234170/