我有一个小型的客户端应用程序,设计为在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
我发现 这个Python脚本并对其进行了逆向工程,以产生一个。处理WinAPI CompressionDecompression的快速库。. 基本上,你可以只用 ctypes
并从 Python 调用 WinAPI。请记住,我还没有广泛地测试过这个,但它应该给你一个很好的开始 :)
EDIT: 按照要求,我已经包含了实现的 compress
和 decompress
函数,以防链接中断。
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
这里有一些其他有用的资源,如果你最终要修修补补的话。