How to implement a Lua container (virtual file system) module loader in C#

前端 未结 2 887
无人及你
无人及你 2021-02-10 03:59

Sounds a little bit scary isn\'t it?

Some background information, I want to load a tar archive which contains some lua modules into my C# application using LuaInterface.

2条回答
  •  隐瞒了意图╮
    2021-02-10 04:36

    I finally got the trick ;-)

    One Problem I currently not really understand is that my loader should not return any string. Here is my solution:

    The loader Class itself:

    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)
        {
            string lua_chunk = "";
            string filename = modulename + ".lua";
            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, modulename);
                    string dum = func.ToString();
                    break;
                }
            }
            return func;
        }
        private Stream in_stream_;
        private Lua lua_;
    }
    

    }

    And how to use the loader, I am not sure if all the package stuff is really needed. But I had to wrap up the call with ":" notation and hide it behind my "load_wrapper" function.

            string load_wrapper = "local function load_wrapper(modname)\n return container_module_loader:load(modname)\n end";
            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 \"System\"");
            lua["container_module_loader"] = tar_loader;
            lua.DoString(load_wrapper);
    
            string loader_package = "module('my_loader', package.seeall) \n";
            loader_package += load_wrapper + "\n";
            loader_package += "table.insert(package.loaders, 2, load_wrapper)";
            lua.DoString(loader_package);
            lua.DoFile("./load_modules.lua");
    

    I hope this may also helps some other

提交回复
热议问题