WinApi在python3中的压缩、解压。

问题描述 投票:0回答:1

我有一个小型的客户端应用程序,设计为在windows机器上运行。它是用CC++(更多的是用C语言)编写的。我希望保持它的小型化,因此我不希望使用外部库,而是坚持在客户端使用WinAPI。

另一方面,我有一个用python3实现的后端服务器。这里我很乐意使用任何现有的库。现在我想添加压缩层来提高传输速度。我遇到的问题是,WinAPI似乎只提供了。

// source: https://docs.microsoft.com/en-us/windows/win32/cmpapi/using-the-compression-api
XPRESS
XPRESS with Huffman encoding 
MSZIP  
LZMS

这似乎是一个独特的微软压缩算法的实现,而我无法在python3中找到在服务器端解压数据的方法。

有什么我遗漏的地方吗?我很想听到一些解决方案:)

先谢谢你

更新

我决定使用zlib https:/zlib.net 正如评论中所建议的那样。建议使用ctypes的答案也非常有趣,但不巧的是,我的后台是在UNIX系统上运行的,我在编译我的客户端部分时,又遇到了一些问题,因为zlib又被链接到了Muli-threaded DLL上。

由于我正在编译我的客户端部分,又是多线程CRT(而不是DLL),我遇到了一些问题,因为zlib被链接到Muli-threaded DLL上。如果有人遇到过这样的问题,我在这里找到了一个非常简单的解决方案。https:/yongweiwu.wordpress.com20171002a-journey-of-purely-static-linking.我把它复制粘贴在这里。

zlib
This part requires a small change to the build script (for version 1.2.11).
I need to open win32\Makefile.msc and change all occurrences of ‘-MD’ to ‘-MT’. 
Then these commands will work:

nmake -f win32\Makefile.msc zlib.lib
c++ c winapi compression
1个回答
0
投票

我发现 这个Python脚本并对其进行了逆向工程,以产生一个。处理WinAPI CompressionDecompression的快速库。. 基本上,你可以只用 ctypes 并从 Python 调用 WinAPI。请记住,我还没有广泛地测试过这个,但它应该给你一个很好的开始 :)

EDIT: 按照要求,我已经包含了实现的 compressdecompress 函数,以防链接中断。

def compress(UncompressedBuffer, UncompressedBufferSize, Format, Engine):
    CompressedBuffer = (ctypes.c_ubyte * UncompressedBufferSize)()
    CompressionFormatAndEngine = ctypes.c_uint16(Format.value | Engine.value)

    CompressBufferWorkSpaceSize = ctypes.c_uint32()
    CompressFragmentWorkSpaceSize = ctypes.c_uint32()
    WorkSpace = (CompressFragmentWorkSpaceSize.value * ctypes.c_ubyte)()
    FinalCompressedSize = ctypes.c_uint32()

    WinDLLCall(RtlGetCompressionWorkSpaceSize,
               CompressionFormatAndEngine,
               ctypes.byref(CompressBufferWorkSpaceSize),
               ctypes.byref(CompressFragmentWorkSpaceSize))

    WinDLLCall(RtlCompressBuffer,
              CompressionFormatAndEngine,
              ctypes.byref(UncompressedBuffer),
              ctypes.c_uint32(UncompressedBufferSize),
              ctypes.byref(CompressedBuffer),
              ctypes.c_uint32(UncompressedBufferSize),
              UncompressedChunkSize,
              ctypes.byref(FinalCompressedSize),
              ctypes.byref(WorkSpace))

    return CompressedBuffer, FinalCompressedSize

def decompress(CompressedBuffer, CompressedBufferSize, UncompressedBufferSize, Format):
    UncompressedBuffer = (ctypes.c_ubyte * UncompressedBufferSize)()
    FinalUncompressedSize = ctypes.c_uint32()

    WinDLLCall(RtlDecompressBuffer,
               Format,
               ctypes.byref(UncompressedBuffer),
               ctypes.c_uint32(UncompressedBufferSize),
               ctypes.byref(CompressedBuffer),
               ctypes.c_uint32(CompressedBufferSize),
               ctypes.byref(FinalUncompressedSize))

    return UncompressedBuffer, FinalUncompressedSize

WinAPI函数加载了以下代码。

import ctypes

RtlDecompressBuffer = ctypes.windll.ntdll.RtlDecompressBuffer
RtlCompressBuffer = ctypes.windll.ntdll.RtlCompressBuffer
RtlGetCompressionWorkSpaceSize = ctypes.windll.ntdll.RtlGetCompressionWorkSpaceSize

这里有一些其他有用的资源,如果你最终要修修补补的话。

© www.soinside.com 2019 - 2024. All rights reserved.