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

余生颓废 提交于 2019-12-18 08:55:09

问题


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().

Since luaL_loadstring(lua_State *L, const char *s) doesn't specify any filename, I don't know how to use require() to load this script from other script.

Does require() only works with actual .lua files?


回答1:


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



回答2:


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.



来源:https://stackoverflow.com/questions/50896799/is-it-possible-to-require-a-script-that-is-loaded-using-lual-loadstring

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!