假设我有一个像这样的“test.lua”文件:
myVar = 5
Food = function()
end
如果我通过loadfile或Lua API(用C ++或其他)加载文件并运行它,变量将保存在全局命名空间_G下;但是,我想分开使用它们,比如_test.myVar和_G.myVar。 (原因是我希望只有该文件中的变量列表)。谢谢。
答案 0 :(得分:5)
在运行脚本之前使用lua_setfenv
。
答案 1 :(得分:1)
module('_test')
myVar = 5
Food = function()
end
然后,从其他文件:
require 'test.lua' --> or loadfile('test.lua')()
print(myVar) --> nil
print(Food) --> nil
print(_test.myVar) --> 5
print(_test.Food) --> function
答案 2 :(得分:1)
lhf说了什么。
为了在面对可能不是来自完全受信任的来源的文件时提供额外的稳健性,您应该在wiki上阅读sandboxing。
关键的想法是要小心在数据文件的上下文中执行的代码可以使用哪些全局函数和变量。对此进行大量控制的一种简单方法是构造环境表,该表将全局变量提供给脚本,以便它只包含安全函数的白名单。您可以通过构造一个合适的表,然后在调用它之前将其设置为新编译的脚本的环境来完成此操作。来自C API的lua_setfenv()
或来自Lua端的setfenv
都可以用于成功调用luaL_loadfile()
,loadfile
或其中一位亲属所返回的对象分别是C API或Lua。加载脚本并分配环境后,您可以使用lua_pcall()
或pcall
运行该脚本。
不要忘记检查所有错误。
当脚本完成时,它创建的变量已在其环境表中编写或更新,而不是_G
。
当然,该环境表可以使用metatable来使您提供脚本的一些全局变量也是有效的。
为了进一步控制,有些人进一步采取了这个想法,并安排限制虚拟指令周期的数量或允许脚本运行的实际时钟时间。甚至可以在加载某些操作码后检查字节码。这可以用于防止在许多情况下甚至尝试执行包含循环的脚本。