Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Lua 卢阿';要求';但是文件只在内存中_Lua - Fatal编程技术网

Lua 卢阿';要求';但是文件只在内存中

Lua 卢阿';要求';但是文件只在内存中,lua,Lua,设置:我正在使用C/C++环境中的Lua 我在磁盘上有几个lua文件。这些文件被读入内存,在运行时,一些更多的仅内存的lua文件变得可用。例如,考虑一个编辑器,其中包含其他未保存的lua文件 因此,我在内存中有一个列表。其中一些文件中有require语句。当我尝试将所有这些文件加载到lua实例时(当前通过lua\u dostring),我得到尝试调用全局require(一个nil值) 是否有可能提供一个require函数,该函数取代旧函数,只使用内存中提供的文件(这些文件位于C端) 是否有其他方

设置:我正在使用C/C++环境中的Lua

我在磁盘上有几个lua文件。这些文件被读入内存,在运行时,一些更多的仅内存的lua文件变得可用。例如,考虑一个编辑器,其中包含其他未保存的lua文件

因此,我在内存中有一个
列表。其中一些文件中有
require
语句。当我尝试将所有这些文件加载到lua实例时(当前通过
lua\u dostring
),我得到
尝试调用全局require(一个nil值)

是否有可能提供一个
require
函数,该函数取代旧函数,只使用内存中提供的文件(这些文件位于C端)

是否有其他方法允许在这些文件中使用
require
,而不在磁盘上存储所需的文件


例如,只从内存加载lua stdlib而不修改它。(实际上这是我的测试用例)

< P>一个非常简单的C++函数,它模仿<>代码>要求< /C> >可以是(伪代码)

int my_require(lua_State*State){
//获取模块名
const char*name=lua_tostring(状态);
//查找是否已加载此类模块
if(mymodules.find(name)!=mymodules.end())
luaL_loadbuffer(状态、缓冲区、大小、名称);
//块现在位于堆栈的顶部
lua_呼叫(州)
返回1;
}
将此函数作为
require
向Lua公开,就可以开始了


我还想补充一点,为了完全模仿
require
的行为,您可能需要注意
包。加载的
,以避免代码被加载两次。

与其替换
require
,为什么不在
包中添加一个函数。加载程序
?代码几乎相同

int my_loader(lua_State*State){
//获取模块名
const char*name=lua_tostring(状态);
//查找是否已加载此类模块
if(mymodules.find(name)!=mymodules.end())
{
luaL_loadbuffer(状态、缓冲区、大小、名称);
//块现在位于堆栈的顶部
返回1;
}
//什么也没找到
返回0;
}
//加载lua状态时,将其插入package.loaders

lua 5.2中没有包裹装载机
它现在叫package.searchers

#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;
}
#包括
#包括
#包括
std::字符串模块_脚本;
int MyLoader(lua_状态*L)
{
const char*name=luaL_checkstring(L,1);//模块名
//std::string result=SearchScript(name);//搜索数据库。
std::string result=module_script;//仅用于演示。
if(luaL_loadbuffer(L,result.c_str(),result.size(),name))
{
printf(“%s”,lua_tostring(L,-1));
卢厄波普(L,1);
}
返回1;
}
void SetLoader(lua_State*L)
{
lua_寄存器(L,“我的加载程序”,MyLoader);
std::字符串str;
//str+=“table.insert(package.loaders,2,my\u loader)\n”//比LuaV5.2旧
str+=“table.insert(package.searchers,2,my\u loader)\n”;
luaL_dostring(L,str.c_str());
}
void SetModule()
{
std::字符串str;
str+=“打印([[它是add.lua]])\n”;
str+=“return{func=function()打印([[messagefrom add.lua]])end}\n”;
模块_script=str;
}
void LoadMainScript(lua_State*L)
{
std::字符串str;
str+=“dev=require[[add]]\n”;
str+=“打印([[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));
卢厄波普(L,1);
返回;
}
}
int main()
{
lua_State*L=luaL_newstate();
luaL_openlibs(L);
SetModule(L);//在内存中写下模块。Lua尚未加载它。
设置加载器(L);
LoadMainScript(L);
lua_pcall(L,0,0,0);
卢厄关闭(L);
返回0;
}

对不起,我不是Lua专家。我想在从内存加载文件之前,我会向lua实例提供名为
require
的函数?@MikeM请查看我对
包路径的编辑,我觉得这可能是我忘记提到的一件重要的事情。lua_call
不需要3个参数吗?我试图拥有自己的
包。已加载
,在第二次加载包时设置为true to require。但这不起作用。在我看来,我真的必须为每个需求将文件放在堆栈上。但是,由于我的内存中有这些文件,因此不必再次加载它们@你觉得这合理吗?顺便说一句,
lua_调用
确实需要3个参数,但是我用
luaL_dostring
替换了loadbuffer和call,这很好,“合理”取决于您的用例。Lua的默认行为(未嵌入时)是只加载每个文件一次,然后填充
包.path
。非常感谢,效果也很好。因为它似乎是更好的解决方案,因为它隐式地处理package.loaded,所以我将接受的解决方案更改为此。