lua中使用require后全局变量丢失的问题
问题是,使用"require"关键字会清除同一文件中定义的所有全局变量。
我正在C++项目中使用Lua 5.3进行开发。我的Lua脚本风格是:
1.所有Lua代码都包含一个公共库文件,以及多个充当函数的小文件。
2.当程序启动时,Lua公共库会被编译并运行,在Lua状态中留下其全局变量。然后编译小文件,但不执行。
3.当程序到达某一点时,相关的小Lua文件将被调用(就像我说的,每个小文件都是一个函数)。在小Lua文件中使用公共库中定义的全局函数和变量。这就是为什么程序启动时我编译并执行公共库的原因。
4.我非常确定我只使用了一个Lua_State。
它一直工作得很好,直到我决定将公共库拆分为多个文件,并在主文件中使用"require"。当程序启动时,将编译并执行主文件。
没有任何代码更改,只是添加了一些"require"。奇怪的事情发生了:所有全局变量和全局函数都丢失了。当在小Lua文件中调用全局函数时,会引发一个"called a nil value"错误。
然后我进行了一个实验,我删除了主库文件中的所有"require"行,结果发现主库中定义的全局函数工作得非常好。然后,我要求一个名为"simple.lua"的空文件,定义在主库中的全局函数丢失了,无法从小Lua文件中调用。
如何解释这个问题?为什么"require"关键字会清除同一文件中定义的所有全局变量?
在Lua库中:
require("simple")
function foo()
return 1+1
end
在小Lua文件中:
return foo()
结果:尝试调用一个空值(全局'foo')
删除"require"后,在Lua库中:
function foo()
return 1+1
end
结果:没有错误发生,返回2。
C++端代码:
Lua公共库编译和执行:
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 ""; //空字符串表示没有错误
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 ""; //返回空值表示没有错误
}
在两个代码中的L是相同的Lua状态(否则删除"require"时不会起作用)。编译后,小文件函数在堆栈顶部被保存在全局寄存器中,并有参考变量"ref"。 调用Lua小文件时,将ref推入堆栈,使用lua_pcall,没有什么特别的。
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的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 代码?

Resolved the problem by myself.
因为复制/粘贴错误,之后会创建第二个lua虚拟机。这很令人困惑,因为如果没有“require”,一切都还好。这只是一个巧合。
我从中学到的是:始终仔细检查复制/粘贴的代码。