Скомпилировать Brotli в a DLL.NET может ссылка

поэтому я хотел бы воспользоваться Brotli, но я не знаком с Python и c++..

Я знаю, что кто-то скомпилировал его в окна .исполняемый. Но как я могу обернуть его в DLL или что-то, на что может ссылаться приложение .NET? Я знаю, что есть IronPython, я просто привожу все исходные файлы в проект IronPython и пишу адаптер .NET, который вызывает API Brotli и предоставляет их? Но на самом деле я даже не уверен, является ли API Brotli Python или c++..

смотрим tools/bro.cc, похоже, что методы "entry" определены в encode.c и decode.c as BrotliCompress(), BrotliDecompressBuffer(), BrotliDecompressStream() методы. Поэтому я полагаю, что DLL может быть скомпилирована из классов C++.

3 ответов


вы можете использовать Brotli.NET который обеспечивает полную поддержку потока.

  1. github:https://github.com/XieJJ99/brotli.net/.
  2. Nuget:https://www.nuget.org/packages/Brotli.NET/.

чтобы сжать поток в данные brotli:

   public Byte[] Encode(Byte[] input)
   {
       Byte[] output = null;
       using (System.IO.MemoryStream msInput = new System.IO.MemoryStream(input))
       using (System.IO.MemoryStream msOutput = new System.IO.MemoryStream())
       using (BrotliStream bs = new BrotliStream(msOutput, System.IO.Compression.CompressionMode.Compress))
       {
           bs.SetQuality(11);
           bs.SetWindow(22);
           msInput.CopyTo(bs);
           bs.Close();
           output = msOutput.ToArray();
           return output;
       }
   }

чтобы распаковать поток brotli:

   public Byte[] Decode(Byte[] input)
   {
       using (System.IO.MemoryStream msInput = new System.IO.MemoryStream(input))
       using (BrotliStream bs = new BrotliStream(msInput, System.IO.Compression.CompressionMode.Decompress))
       using (System.IO.MemoryStream msOutput = new System.IO.MemoryStream())
       {
           bs.CopyTo(msOutput);
           msOutput.Seek(0, System.IO.SeekOrigin.Begin);
           output = msOutput.ToArray();
           return output;
       }

   }

поддержка динамического сжатия в веб-приложениях,добавьте такой код в Глобальный.асакс.cs:

    protected void Application_PostAcquireRequestState(object sender, EventArgs e)
    {
                       var app = Context.ApplicationInstance;
            String acceptEncodings = app.Request.Headers.Get("Accept-Encoding");

            if (!String.IsNullOrEmpty(acceptEncodings))
            {
                System.IO.Stream baseStream = app.Response.Filter;
                acceptEncodings = acceptEncodings.ToLower();

                if (acceptEncodings.Contains("br") || acceptEncodings.Contains("brotli"))
                {
                    app.Response.Filter = new Brotli.BrotliStream(baseStream, System.IO.Compression.CompressionMode.Compress);
                    app.Response.AppendHeader("Content-Encoding", "br");
                }
                else
                if (acceptEncodings.Contains("deflate"))
                {
                    app.Response.Filter = new System.IO.Compression.DeflateStream(baseStream, System.IO.Compression.CompressionMode.Compress);
                    app.Response.AppendHeader("Content-Encoding", "deflate");
                }
                else if (acceptEncodings.Contains("gzip"))
                {
                    app.Response.Filter = new System.IO.Compression.GZipStream(baseStream, System.IO.Compression.CompressionMode.Compress);
                    app.Response.AppendHeader("Content-Encoding", "gzip");
                }

            }
       }        

чтобы избежать необходимости в Python, я разветвил исходный источник brotli здесь https://github.com/smourier/brotli и создал версию Windows DLL, с которой вы можете использовать .Сеть. Я добавил каталог, содержащий решение "WinBrotli" Visual Studio 2015 с двумя проектами:

  • WinBrotli: DLL Windows (x86 и x64), которая содержит исходный неизмененный код C/C++ brotli.
  • кодом Brotli: консоль Windows Приложение (любой процессор), написанное на C#, которое содержит код взаимодействия P/Invoke для WinBrotli.

чтобы повторно использовать DLL Winbrotli, просто скопируйте WinBrotli.х64.dll и WinBrotli.архитектуры x86.dll (вы можете найти уже построенные версии выпуска в WinBrotli / двоичные файлы папка) в сторону вашего приложения .NET и включить BrotliCompression.cs файл в вашем проекте C# (или перенесите его на VB или другой язык, если C# не является вашим любимым языком). Код взаимодействия будет автоматически выберите нужную DLL, соответствующую разрядности текущего процесса (X86 или X64).

Как только вы это сделаете, использовать его довольно просто (вход и выход могут быть пути к файлам или стандартные потоки .NET):

        // compress
        BrotliCompression.Compress(input, output);

        // decompress
        BrotliCompression.Decompress(input, output);

чтобы создать WinBrotli, вот что я сделал (для других, которые хотели бы использовать другие версии Visual Studio)

  • создал стандартный проект DLL, удалил предварительно скомпилированный заголовок
  • включены все кодировщик и декодер оригинальные файлы brotli C / C++ (никогда ничего не меняли, поэтому при необходимости мы можем обновить исходные файлы)
  • настроил проект для удаления зависимостей от MSVCRT (поэтому нам не нужно развертывать другую DLL)
  • отключено предупреждение 4146 (в противном случае мы просто не можем скомпилировать)
  • добавлен очень стандартный dllmain.cpp файл, который не делает ничего особенного
  • добавлен WinBrotli.cpp-файл, который предоставляет код сжатия и декомпрессии brotli снаружи Windows world (с очень тонким адаптационным слоем, поэтому проще взаимодействовать в .NET)
  • добавлен WinBrotli.def файл, который экспортирует 4 функции

я покажу один из способов сделать это, вызвав родную библиотеку python из кода .NET. Что вам нужно:

  1. вам нужно intall python 2.7 (надеюсь, это очевидно)
  2. вам нужно скомпилировать brotli из исходного кода. Надеюсь, это легко. Первая установка компилятор Microsoft Visual C++ для Python 2.7. Затем клонируйте репозиторий brotli через git clone https://github.com/google/brotli.git и скомпилировать с помощью python setup.py build_ext. Когда это будет сделано, в build\lib.win32-2.7 каталог вы найдете . Это python C++ module-он нам понадобится позже.

  3. вам нужно либо скачать pythonnet двоичные файлы или скомпилировать его из источника. Причина, по которой мы используем pythonnet здесь, а не, например, Iron Python, заключается в том, что Iron Python не поддерживает собственные (C\C++) модули python, и это то, что нам нужно здесь. Итак, чтобы скомпилировать из источника, клонируйте через git clone https://github.com/pythonnet/pythonnet.git затем скомпилировать через python setup.py build. В результате вы получите Python.Во время выполнения.dll (in build\lib.win32-2.7 - каталог), что мы необходимость.

когда у вас есть все это на месте, создайте консольный проект, ссылку на Python.Во время выполнения.dll, а затем:

public static void Main()
{            
    PythonEngine.Initialize();            
    var gs = PythonEngine.AcquireLock();
    try {                
        // import brotli module
        dynamic brotli = PythonEngine.ImportModule(@"brotli");
        // this is a string we will compress
        string original = "XXXXXXXXXXYYYYYYYYYY";
        // compress and interpret as byte array. This array you can save to file for example
        var compressed = (byte[]) brotli.compress(original);                
        // little trick to pass byte array as python string
        dynamic base64Encoded = new PyString(Convert.ToBase64String(compressed));
        // decompress and interpret as string
        var decompressed = (string) brotli.decompress(base64Encoded.decode("base64"));
        // works
        Debug.Assert(decompressed == original);
    }
    finally {
        PythonEngine.ReleaseLock(gs);
        PythonEngine.Shutdown();
    }            
    Console.ReadKey();
}

тогда постройте это и положить кодом Brotli.пыць вы получаете выше в том же каталоге с вашим .файл EXE. После всех этих манипуляций вы сможете сжимать и распаковывать из .NET-кода, как вы видите выше.