是否可以 require() 使用 luaL_loadstring() 加载的脚本?

Is it possible to require() a script that is loaded using luaL_loadstring()?

我是 Lua 的初学者。

我想知道是否可以使用 require('filename') 来要求使用 luaL_loadstring().

加载的脚本

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

require() 是否仅适用于实际的 .lua 文件?

好吧,看看the documentation for require(),你会发现它非常灵活。

相关部分是:

  1. package.loaded[modname]。只需将其设置为您想要的模块名称即可。不过,请务必先设置它 require
  2. package.searchers 和其中的默认条目。这仅在模块未注册为已加载时才相关。

更详细:

如果你想为 require 设置一个包来找到它,你有两个选择:1. 通过将它添加到 package.loaded 来将它设置为完全加载,或者 2. 确保它被找到package.searchers 条目之一。
Any competent lua modules tutorial 将告诉您如何轻松地构造模块本身,文档也为您提供了原因的机制。
The registry, which contains an entry for the global environment,可以从本机代码访问,因此如果您愿意,可以从那里进行。

luaL_loadstring 创建一个 Lua 函数,该函数在调用时执行给定的字符串。我们可以使用这个事实,因为 Lua C 模块也简单地调用一个函数 luaopen_MODULE。这个函数 return 是一个 table 模块内容。也就是说,如果我们想通过 luaL_loadstring 加载模块,作为字符串给出的脚本 必须 return 一个 table。剩下要做的唯一一件事就是让解释器知道在哪里可以找到模块。因此,我们只需在 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);

    // ---- Register our "fromstring" module ----
    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