Lua C API - 加载多个具有相同名称的变量和函数的文件
2020-5-8 17:46:3
收藏:0
阅读:243
评论:2
假设我有两个使用标准Lua C API的Lua文件,共享一个公共库:
common.lua
function printHello(name)
print("Hello from " .. name)
end
file1.lua
require "common"
local scriptName = "file1"
function doSomething()
printHello(scriptName)
end
file2.lua
require "common"
local scriptName = "file2"
function doSomething()
printHello(scriptName)
end
现在假设我想让file*.lua文件共享相同的 lua_State。
在不改变任何Lua代码的情况下,如何以一种方式加载文件,以便我可以调用特定的 doSomething()呢?
是否有一种方法可以将从加载的文件(函数,变量,表)中的“一切”移动到 lua_State 中的全局表中,使用脚本名称(或其他内容)作为键?另外,是否有一种方法可以使file1.lua和file2.lua共享common.lua的“内存”版本?
我正在使用Lua 5.1。
谢谢!
点赞
用户4256006
FYI,上述答案现在已经不能在最新版本的LUA中使用。具体来说,
和
不再受支持。由于我是一个LUA新手,我不知道应该使用哪些等效的LUA api调用来替换它们。如果有人能更新那个答案,让它适用于LUA 5.4,那将不胜感激。我很抱歉我没有遵循协议,没有直接在答案中评论,但显然我没有足够的声誉来这样做。
2022-03-04 15:06:08
评论区的留言会收到邮件通知哦~
推荐文章
- 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 代码?

以下是如何在纯 Lua 5.1 中实现:
file1_env = setmetatable({}, {__index = _G}) local file1_chunk = loadfile('file1.lua') setfenv(file1_chunk, file1_env) file1_chunk() file2_env = setmetatable({}, {__index = _G}) local file2_chunk = loadfile('file2.lua') setfenv(file2_chunk, file2_env) file2_chunk() file1_env.doSomething() -- 输出 "Hello from file1" file2_env.doSomething() -- 输出 "Hello from file2"实际上改变了每个文件块运行的环境,所以它们的“doSomething”函数不再在全局环境中,这样它们就可以使用自己的局部环境(其中使用了 metatable,因此它们可以使用全局环境中的东西,例如“require”和“print”)。如所请求的,'common.lua'只需运行一次,如果在其末尾放置像“printHello('common')”这样的语句,则会看到。
如果要从 C 中执行此操作,则可以将我使用的所有功能直接转换为 C API,如下所示:
#include <lua5.1/lua.h> #include <lua5.1/lualib.h> #include <lua5.1/lauxlib.h> int main(void) { lua_State *L = luaL_newstate(); luaL_openlibs(L); /* stack is empty */ lua_createtable(L, 0, 1); /* -1: file1_env */ lua_createtable(L, 0, 1); /* -2: file1_env, -1: file1_env_mt */ lua_pushvalue(L, LUA_GLOBALSINDEX); /* -3: file1_env, -2: file1_env_mt, -1: _G */ lua_setfield(L, -2, "__index"); /* -2: file1_env, -1: file1_env_mt */ lua_setmetatable(L, -2); /* -1: file1_env */ luaL_loadfile(L, "file1.lua"); /* -2: file1_env, -1: file1_chunk */ lua_pushvalue(L, -2); /* -3: file1_env, -2: file1_chunk, -1: file1_env */ lua_setfenv(L, -2); /* -2: file1_env, -1: file1_chunk */ lua_call(L, 0, 0); /* -1: file1_env */ lua_setglobal(L, "file1_env"); /* stack is empty */ lua_createtable(L, 0, 1); /* -1: file2_env */ lua_createtable(L, 0, 1); /* -2: file2_env, -1: file2_env_mt */ lua_pushvalue(L, LUA_GLOBALSINDEX); /* -3: file2_env, -2: file2_env_mt, -1: _G */ lua_setfield(L, -2, "__index"); /* -2: file2_env, -1: file2_env_mt */ lua_setmetatable(L, -2); /* -1: file2_env */ luaL_loadfile(L, "file2.lua"); /* -2: file2_env, -1: file2_chunk */ lua_pushvalue(L, -2); /* -3: file2_env, -2: file2_chunk, -1: file2_env */ lua_setfenv(L, -2); /* -2: file2_env, -1: file2_chunk */ lua_call(L, 0, 0); /* -1: file2_env */ lua_setglobal(L, "file2_env"); /* stack is empty */ lua_getglobal(L, "file1_env"); /* -1: file1_env */ lua_getfield(L, -1, "doSomething"); /* -2: file1_env, -1: file1_env.doSomething */ lua_call(L, 0, 0); /* -1: file1_env */ lua_pop(L, 1); /* stack is empty */ lua_getglobal(L, "file2_env"); /* -1: file2_env */ lua_getfield(L, -1, "doSomething"); /* -2: file2_env, -1: file2_env.doSomething */ lua_call(L, 0, 0); /* -1: file2_env */ lua_pop(L, 1); /* stack is empty */ lua_close(L); return 0; }