Скомпилировать 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 который обеспечивает полную поддержку потока.
чтобы сжать поток в данные 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. Что вам нужно:
- вам нужно intall python 2.7 (надеюсь, это очевидно)
вам нужно скомпилировать 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-он нам понадобится позже.вам нужно либо скачать pythonnet двоичные файлы или скомпилировать его из источника. Причина, по которой мы используем pythonnet здесь, а не, например, Iron Python, заключается в том, что Iron Python не поддерживает собственные (C\C++) модули python, и это то, что нам нужно здесь. Итак, чтобы скомпилировать из источника, клонируйте через
git clone https://github.com/pythonnet/pythonnet.git
затем скомпилировать черезpython setup.py build
. В результате вы получите Python.Во время выполнения.dll (inbuild\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-кода, как вы видите выше.