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