将编译后的字符串分配自定义模块名称 C-LuaJit

我有一个小的 C 程序,其中有一个字符串必须表示一个 Lua 模块,它看起来像这样:

const char *lua_str = " local mymodule = {} \
    function mymodule.foo() \
        print(\"Hello World!\") \
    end
    return mymodule";

或者也可以使用旧的方式(_如果需要_):

const char *lua_str = "module(\"mymodule\", package.seeall \
    function foo() \
        print(\"Hello World!\") \
    end";

假设这是我的小型主机应用程序:

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

int main(int argc, char** argv)
{
    lua_State *L = lua_open();
    luaL_openlibs(L);

    luaL_dostring(L, lua_str);
    luaL_dofile(L, "test.lua");

    return 0;
}

现在在 test.lua 中,为了能够使用具有 静态 名称的该模块,该名称不由文件名决定:

local mymodule = require "mymodule"
mymodule.foo()

基本上,我需要执行该字符串并给其一个自定义名称,表示实际的模块名称。目前该名称是由文件名决定的,我不想这样。

点赞
用户258523
用户258523

如果你查看require的文档:

加载给定的模块。函数首先查找package.loaded表来确定modname是否已经被加载。如果已经加载,则require返回package.loaded[modname]中存储的值。否则,它尝试查找模块的加载器。

为了找到一个加载器,require根据package.loaders数组进行引导。通过更改该数组,我们可以更改require查找模块的方式。以下解释基于package.loaders的默认配置。

首先,对package.preload[modname]进行查询。如果有值,则该值(应为函数)是加载器。否则,将使用package.path中存储的路径查找Lua加载器。如果仍然失败,则使用package.cpath中存储的路径查找C加载器。如果仍然失败,则尝试使用all-in-one loader(请参阅package.loaders)。

找到加载器后,require将使用单个参数modname调用加载器。如果加载器返回任何值,则require将返回该值并为package.loaded[modname]赋值。如果加载器未返回任何值,并且未为package.loaded[modname]分配任何值,则require将为此条目分配true。无论如何,require都会返回package.loaded[modname]的最终值。

如果加载或运行模块时出现任何错误,或者它找不到模块的任何加载器,则require会发出错误信号。

你可以看到,它详细地解释了require使用的方法来查找给定模块名称的代码。在这个解释中,暗示着你可以将任意加载(或可加载)代码块分配给任何给定的名称。

具体来说,如果在package.loaded[modname]中设置一个值,该值将立即返回。如果失败,则使用package.preload[modname]作为加载器(加载器是一个以模块名称为参数的函数)。

2014-09-05 01:23:19