gra*_*ans 5 c# lua module tar luainterface
听起来有点可怕不是吗?
一些背景信息,我想使用LuaInterface将包含一些lua模块的tar存档加载到我的C#应用程序中.最简单的方法是将这些文件解压缩到临时文件夹,修改lua模块搜索路径并像往常一样用require读取它们.但我不想把这些脚本放在文件系统的某个地方.
所以我认为应该可以使用#ziplib加载tar-archive 我知道有很多用于tar的lua实现和类似的东西.但#zlib已经是该项目的一部分.
成功将文件作为字符串(流)从存档中加载后,我应该能够通过LuaInterface将它们传递给C#中的lua.DoString(...).
但是,如果模块有这样的行,那么简单地通过dostring或dofile加载模块就不起作用了:"module(...,package.seeall)"有一个错误报告,比如将参数1传递给nil,但是字符串是预期的.
另一个问题是模块可能依赖于也位于tar存档中的其他模块.
一种可能的解决方案应该是定义这里描述的自定义加载器.
我的想法是使用#ziplib在C#中实现这样的加载器,并将此加载器映射到我的C#应用程序的lua堆栈中.
你们中有谁有类似的任务吗?有没有现成的解决方案已经解决了这样的问题?
tar文件不是必须的,但包装格式很好.
这个想法是可行还是完全不可行?
我写了一些示例类来从存档中提取lua文件.此方法用作加载器并返回lua函数.
namespace LuaInterfaceTest
{
class LuaTarModuleLoader
{
private LuaTarModuleLoader() { }
~LuaTarModuleLoader()
{
in_stream_.Close();
}
public LuaTarModuleLoader(Stream in_stream,Lua lua )
{
in_stream_ = in_stream;
lua_ = lua;
}
public LuaFunction load(string modulename, out string error_message)
{
string lua_chunk = "test=hello";
string filename = modulename + ".lua";
error_message = "Unable to locate the file";
in_stream_.Position = 0; // rewind
Stream gzipStream = new BZip2InputStream(in_stream_);
TarInputStream tar = new TarInputStream(gzipStream);
TarEntry tarEntry;
LuaFunction func = null;
while ((tarEntry = tar.GetNextEntry()) != null)
{
if (tarEntry.IsDirectory)
{
continue;
}
if (filename == tarEntry.Name)
{
MemoryStream out_stream = new MemoryStream();
tar.CopyEntryContents(out_stream);
out_stream.Position = 0; // rewind
StreamReader stream_reader = new StreamReader(out_stream);
lua_chunk = stream_reader.ReadToEnd();
func = lua_.LoadString(lua_chunk, filename);
string dum = func.ToString();
error_message = "No Error!";
break;
}
}
return func;
}
private Stream in_stream_;
private Lua lua_;
}
Run Code Online (Sandbox Code Playgroud)
}
我尝试在LuaInterface中注册这样的加载方法
Lua lua = new Lua();
GC.Collect();
Stream inStream = File.OpenRead("c:\\tmp\\lua_scripts.tar.bz2");
LuaTarModuleLoader tar_loader = new LuaTarModuleLoader(inStream, lua);
lua.DoString("require 'CLRPackage'");
lua.DoString("import \"ICSharpCode.SharpZipLib.dll\"");
lua.DoString("import \"System\"");
lua["container_module_loader"] = tar_loader;
lua.DoString("table.insert(package.loaders, 2, container_module_loader.load)");
lua.DoString("require 'def_sensor'");
Run Code Online (Sandbox Code Playgroud)
如果我这样尝试,我会在调用require时遇到异常:
"实例方法'加载'需要非空目标对象"
我试着直接调用load方法,这里我必须使用":"符号.
lua.DoString("container_module_loader:load('def_sensor')");
Run Code Online (Sandbox Code Playgroud)
如果我调用这样的方法,我在调试器中点了一个断点,它位于方法之上,所以一切都按预期工作.
但是如果我尝试用":"符号注册方法,我在注册方法时会遇到异常:
lua.DoString("table.insert(package.loaders, 2, container_module_loader:load)");
Run Code Online (Sandbox Code Playgroud)
"[string"chunk"]:1:预期在')'附近的函数参数
在L\xc3\x96VE中,他们可以做到这一点。所有 Lua 文件都位于一个 zip 文件内,即使...使用,它们也能正常工作。他们使用的库是PhysicsFS。
看看源码。也许 /modules/filesystem 会让你开始。
\n