Lua 'require' but files are only in memory

前端 未结 3 848
甜味超标
甜味超标 2021-02-14 16:59

Setting: I\'m using Lua from a C/C++ environment.

I have several lua files on disk. Those are read into memory and some more memory-only lua files become available duri

相关标签:
3条回答
  • 2021-02-14 17:24

    A pretty straightforward C++ function that would mimic require could be: (pseudocode)

    int my_require(lua_State* state) {
        // get the module name
        const char* name = lua_tostring(state);
        // find if you have such module loaded
        if (mymodules.find(name) != mymodules.end())
            luaL_loadbuffer(state, buffer, size, name);
        // the chunk is now at the top of the stack
        lua_call(state)
        return 1;
    }
    

    Expose this function to Lua as require and you're good to go.

    I'd also like to add that to completely mimic require's behaviour, you'd probably need to take care of package.loaded, to avoid the code to be loaded twice.

    0 讨论(0)
  • 2021-02-14 17:39

    Instead of replacing require, why not add a function to package.loaders? The code is nearly the same.

    int my_loader(lua_State* state) {
        // get the module name
        const char* name = lua_tostring(state);
        // find if you have such module loaded
        if (mymodules.find(name) != mymodules.end())
        {
            luaL_loadbuffer(state, buffer, size, name);
            // the chunk is now at the top of the stack
            return 1;
        }
    
        // didn't find anything
        return 0;
    }
    
    // When you load the lua state, insert this into package.loaders
    

    http://www.lua.org/manual/5.1/manual.html#pdf-package.loaders

    0 讨论(0)
  • 2021-02-14 17:45

    There is no package.loaders in lua 5.2
    It called package.searchers now.

    #include <stdio.h>
    #include <string>
    #include <lua.hpp>
    
    std::string    module_script;
    
    
    int MyLoader(lua_State *L)
    {
        const char *name = luaL_checkstring(L, 1);  // Module name
    
    //  std::string    result = SearchScript(name); // Search your database.
        std::string    result = module_script;      // Just for demo.
    
        if( luaL_loadbuffer(L, result.c_str(), result.size(), name) )
        {
            printf("%s", lua_tostring(L, -1));
            lua_pop(L, 1);
        }
    
        return 1;
    }
    
    void SetLoader(lua_State* L)
    {
        lua_register(L, "my_loader", MyLoader);
    
        std::string     str;
    
    //  str += "table.insert(package.loaders,   2, my_loader) \n";   // Older than lua v5.2
        str += "table.insert(package.searchers, 2, my_loader) \n";
    
        luaL_dostring(L, str.c_str());
    }
    
    void SetModule()
    {
        std::string     str;
    
        str += "print([[It is add.lua]]) \n";
        str += "return { func = function() print([[message from add.lua]]) end } \n";
    
        module_script=str;
    }
    
    void LoadMainScript(lua_State* L)
    {
        std::string     str;
    
        str += "dev = require [[add]] \n";
        str += "print([[It is main.lua]]) \n";
        str += "dev.func() \n";
    
        if ( luaL_loadbuffer(L, str.c_str(), str.size(), "main") )
        {
            printf("%s", lua_tostring(L, -1));
            lua_pop(L, 1);
            return;
        }
    }
    
    int main()
    {
        lua_State*  L = luaL_newstate();
    
        luaL_openlibs(L);
    
        SetModule(L);       // Write down module in memory. Lua not load it yet.
        SetLoader(L);
        LoadMainScript(L);
    
        lua_pcall(L,0,0,0);
        lua_close(L);
    
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题