在5.2中沙盒嵌入Lua / 为来自lua.file的函数设置环境
2017-5-23 12:15:51
收藏:0
阅读:360
评论:2
假设我至少有两个 Lua 脚本文件。
test1.lua test2.lua
两个文件都定义了一个 init 函数和其他类似名称的函数。
我该如何使用 Lua 5.2 将每个脚本文件加载到一个单独的环境中,以避免相同的函数名称冲突?我找到了一个 5.1 的示例代码,但无法使用(因为 setenv 已被删除,而 lua_setuservalue 似乎不起作用)。
示例在这里 Calling lua functions from .lua's using handles?
基本上,如果我将 setenv 替换为 setuservalue,则会出现访问冲突。
点赞
用户734069
两者都定义了一个初始化函数和其他类似名称的函数。
首先,为什么这些函数是全局的?它们应该是脚本的局部变量。如果你要在其他文件中require它们,它们应该创建并返回一个包含要公开的函数的表格。
现代的做法是,在需要这些文件的地方做如下操作:
local Library = require 'library'
Library.Func1(...)
这样不会污染全局 Lua 命名空间。你使用局部变量。
但是,如果你坚持像这样使用全局变量,你可以按照文档所说的那样:更改已编译代码块的第一个上值。
如果我将
setenv替换为setuservalue- 我会得到访问冲突的错误。
当然会,这不是lua_setuservalue的作用。它用于设置与用户数据相关联的值。你需要的是被适当称作lua_setupvalue的函数。
在使用你提到的示例代码时,正确的做法是:
lua_setupvalue(L,-2,1);
2012-06-13 14:31:58
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的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 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
非官方 Lua 常见问题解答 中有关于 Lua 沙盒的条目。我的猜想是,你可以很容易地将该逻辑转换到你的 C/C++ 代码上。
另外请参见 lua-users wiki 上的 LuaFiveTo。
更正
事实上并不像看上去的那么简单。但是最终的目标很简单:加载代码块,推入 _ENV 表,使用
lua_setupvalue(L,-2,1)。重要的是,该表应该在堆栈的顶部。作为一个小例子,使用两个默认为 _G 的环境来通过元表读取内容:
#include <lua.h> #include <lualib.h> #include <lauxlib.h> int main(void){ lua_State *L = luaL_newstate(); char *file1 = "file1.lua"; char *file2 = "file2.lua"; luaL_openlibs(L); luaL_loadfile(L,file2); // S: 1 luaL_loadfile(L,file1); // S: 2 lua_newtable(L); // ENV for file 1: S: 321 lua_newtable(L); // ENV for file 2: S: 4321 //让每个函数都有它自己的元表,其中已经有的查找会在全局表_G中进行 lua_newtable(L); // metatable S: 54321 lua_getglobal(L,"_G"); // pushes _G, which will be the __index metatable entry S: 654321 lua_setfield(L,-2,"__index"); // metatable on top S: 54321 lua_pushvalue(L,-1); // copy the metatable S: 554321 lua_setmetatable(L,-3); // set the last copy for env2 S: 54321 lua_setmetatable(L,-3); // set the original for env1 S: 4321 // 这里我们在堆栈上为两个环境有两个表 lua_setupvalue(L,1,1); // 第一个 upvalue == _ENV,所以设置它。S: 321 lua_setupvalue(L,2,1); // 设置文件的 _ENV S: 21 // 堆栈上剩下的是:带有设置环境的2个代码块。 lua_pcall(L,0,LUA_MULTRET,0); lua_pcall(L,0,LUA_MULTRET,0); lua_close(L); return 0; }以及两个 Lua 文件:
-- file1.lua function init() A="foo" print("Hello from file1") print(A) end init() -- file2.lua -- 这表明了在 file1 中定义的内容不会污染 file2 的环境。 print("init function is",tostring(init)) function init() A="bar" print("Hello from file2") print(A) end init()