Lua中有替代package.preload的方案吗?
2018-7-18 5:15:9
收藏:0
阅读:243
评论:2
我发现package.preload可以用于将脚本暴露给其他脚本使用。
这是我的示例代码:
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_settop(L, 0);
//Script A
luaL_dostring(L, "local A = {} package.preload['A'] = function () return A end A.num = 3");
//Script B
luaL_dostring(L, "local A = require 'A' print(A.num)");
lua_close(L);
结果是:3
虽然这个方法可以使用,但是我想知道Script A的代码是否可以更简洁,或是否有其他替代方法来将脚本暴露给其他脚本使用。
补充:我提出这个问题的主要原因是,我认为package.preload['A'] = function () return A end太长而且无聊了。
点赞
用户1944004
似乎您想在定义模块块的每个代码片段中添加 local A = {} package.preload['A'] = function () return A end (其中 A 是模块名称)。 我认为,只需使用字符串连接就可以简单地完成。
#include <string>
#include <lua.hpp>
int preload(lua_State *L, std::string const &modname,
std::string const &modcode) {
std::string code = "package.preload['" + modname + "'] = function()\n" +
"local " + modname + " = {}\n" + modcode + "\n"
"return " + modname + " end";
return luaL_dostring(L, code.c_str());
}
int main() {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
// Script A
preload(L, "A", "A.num = 3");
// Script B
luaL_dostring(L, "local A = require 'A' print(A.num)");
lua_close(L);
}
2018-07-18 05:13:18
评论区的留言会收到邮件通知哦~
推荐文章
- 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 模块的 in-C 字符串集时,“package.preload”正是要使用的工具。尽管您特定的使用留下了一些问题。
一般来说,模块本身并不定义它们的名称。因此,将模块的名称硬编码到字符串中不是正确的方法。类似地,模块不会注册自己;它们应该由围绕模块的环境注册。
你真正想要的是将名称+Lua 代码字符串数组作为模块预加载在循环中注册。因此,您会得到类似这样的结果。我将使用 Lua 5.3;您可以轻松地将其翻译为旧版的 Lua。
还要注意:此代码未经测试。
const char *lua_preloads[] = { "A", "local A = {}\n" "A.num = 3\n" "return A)\n", //模块通常是表而不是函数。 ... NULL // Null-terminated list. }; //加载器函数 int lua_preloader_func(lua_State *L) { int nargs = lua_gettop(L); int lua_func_ix = lua_upvalueindex(1); lua_pushvalue(L, lua_func_ix); //将函数移动到堆栈的底部 lua_insert(lua_func_ix, 1); //用所有给定的参数调用。 lua_call(L, nargs, LUA_MULTRET); return lua_gettop(L); } int top = lua_gettop(L); //获取 package.preload 表。 lua_getglobal(L, "package"); lua_getfield(L, -1, "preload"); int preload_ix = lua_gettop(); for(const char **position = lua_preloads; *position; position += 2) { const char *module_name = position[0]; const char *module = position[1]; //将预装脚本编译成 Lua 函数。 int err = luaL_loadbufferx(L, module, strlen(module), module_name, "t"); //检查 `err` 中的错误。 //使用脚本作为 upvalue 创建 Lua C 函数。 lua_pushcclosure(L, lua_preloader_func, 1); //将该 Lua C 函数放在 package.preload[preload.first] 中。 lua_setfield(L, preload_ix, module_name); } lua_settop(L, top);