能否使用require()加载使用luaL_loadstring()加载的脚本?

我是Lua的初学者。

我想知道是否可能使用require('filename')来加载使用luaL_loadstring()加载的脚本。

由于luaL_loadstring(lua_State *L, const char *s)没有指定任何文件名,我不知道如何从其他脚本中使用require()加载该脚本。

是否仅仅能通过实际的.lua文件来使用require()加载脚本?

点赞
用户3204551
用户3204551

好的,进一步了解一下require()的文档后,你会发现它非常灵活。

相关部分包括:

  1. package.loaded[modname]。只需设置所需的模块名称即可。但在使用require前一定要记得进行设置。
  2. package.searchers和其中的默认条目。仅在模块未注册为已加载时才相关。

详细解释如下:

如果你想设置一个包,让require能够找到它,你有两个选择:1. 将其完全加载后加入到package.loaded中;2. 确保它被package.searchers的某个条目找到。

任何一本优秀的Lua模块教程都会告诉你如何轻松地构建模块本身,而文档则提供了其机制的原因。

注册表,包含全局环境的条目,可以从本地代码中访问,因此如果你愿意的话也可以从那里进行设置。

2018-06-17 13:10:01
用户1944004
用户1944004

luaL_loadstring 创建一个 Lua 函数,当被调用时会执行传递进去的字符串。由于 Lua C 模块其实只是调用函数 luaopen_MODULE,它会返回一个包含模块内容的表。也就是说,如果我们想要通过 luaL_loadstring 加载一个模块,那么作为字符串传入的脚本 _必须返回一个表_。剩下要做的就是让解释器知道如何找到该模块。我们只需要在 package.preload 中创建一项即可。

有趣的部分在虚线之间。其余部分只是为了让解释器运行而预置的代码。(可能不适用于 5.1 版本)

#include <stdio.h>

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <script.lua>\n", argv[0]);
        return 1;
    }

    lua_State * L = luaL_newstate();
    luaL_openlibs(L);

    // ---- 注册我们的 "fromstring" 模块 ----
    lua_getglobal(L, "package");
    lua_getfield(L, -1, "preload");
    luaL_loadstring(L, "return { test = function() print('Test') end }");
    lua_setfield(L, -2, "fromstring");
    // ------------------------------------------

    if (luaL_dofile(L, argv[1]) != 0) {
        fprintf(stderr,"lua: %s\n", lua_tostring(L, -1));
        lua_close(L);
        return 1;
    }

    lua_close(L);
}

输入脚本:

local fromstring = require("fromstring")
fromstring.test()

输出:

Test
2018-06-19 09:38:40