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

前端 未结 2 1053
臣服心动
臣服心动 2020-12-21 06:50

I\'m a beginner in Lua.

I wonder if it is possible to use require(\'filename\') to require a script that is loaded using luaL_loadstring().

相关标签:
2条回答
  • 2020-12-21 07:43

    luaL_loadstring creates a Lua function which, when called, executes the string it was given. We can use this fact, because Lua C modules also simply call a function luaopen_MODULE. This function returns a table with the module content. That is to say, if we want to load a module via luaL_loadstring the script given as a string has to return a table. The only thing left to do is letting the interpreter know where to find the module. Therefore we simply create an entry in package.preload.

    The interesting part is between the dashes. The rest is just boilerplate to get the interpreter running. (Might not work in 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);
    }
    

    Input script:

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

    Output:

    Test
    
    0 讨论(0)
  • 2020-12-21 07:44

    Well, take a peek into the documentation for require(), and you will see it's very flexible.

    The relevant parts are:

    1. package.loaded[modname]. Just set it with the module name you want. Be sure to set it before you require it though.
    2. package.searchers and the default entries therein. This is only relevant if the module is not registered as loaded as noted above.

    In more detail:

    If you want to set up a package for require to find it, you have two choices: 1. Set it up as fully loaded by adding it to package.loaded, or 2. make sure it's found by one of the package.searchers-entries.
    Any competent lua modules tutorial will tell you how to structure the module itself easily, the docs give you the mechanics of why too.
    The registry, which contains an entry for the global environment, can be accessed from native code, so you can do it from there if you so desire.

    0 讨论(0)
提交回复
热议问题