7z作为开源的解压缩项目,支持多种格式的解压缩,由 Igor Pavlov 开发,最新的版本为 19.00 版。
源码下载位置:https://www.7-zip.org/a/7z1900-src.7z
1、源码结构
源码解压之后,是这样的结构:
| 路径 | 备注 |
|---|---|
| Asm | 包含主要算法的汇编实现,直接使用汇编可以提高执行效率。但是却对跨平台移植造成了一些困难 |
| C | 主要是算法的代码,由C语言实现 |
| CPP | 相关COM接口的实现,界面,工程文件等 |
| DOC | 相关文档 |
对于我们编译项目来说,最主要的就是 CPP 文件夹,编译的项目文件在 CPP\7zip\Bundles\ 中可以找到。
| 路径 | 备注 |
|---|---|
| Alone | 独立的可执行程序,支持的解压格式仅包括7z, cab, tar, zip这几种。 |
| Alone7z | 独立的可执行程序,仅支持7z格式。FM文件管理器(File Manager),通过加载7z.dll的导出函数进行解压。 |
| Format7z | 7za.dll 7z Standalone Plugin,7z 独立插件(仅7z格式) |
| Format7zF | 7z.dll 7z Plugin, 7z插件,包含各种格式。 |
| SFXCon | 自解压(控制台程序) |
| SFXSetup | 自解压程序(安装包) |
| SFXWin | 自解压程序(Windows界面)。 |
2、压缩包相关接口
7z.dll 中的每一种支持的格式被称作 Archive,代码位于CPP\7zip\Archive中。
每一种Archive包含一个Handler,Handler里包含处理每一种Archive的接口。
每一种Archive包含一个Register,用于向全局对象注册,只有注册后的Handler才会被调用。
Handler必须继承IInArchive接口,用于传入给Handler的对象,用于解压。(必选)
Handler可以继承IOutArchive接口,用于生成Archive对象,用于压缩文档。(可选)
根据官方说明:Packing / unpacking: 7z, XZ, BZIP2, GZIP, TAR, ZIP and WIM
仅这几种Archive是可以被压缩的,因此这些Archive的Handler要继承IOutArchive接口。
如果代码只用于解压,而不用于压缩,可定义EXTRACT_ONLY宏,可不生成IOutArchive,可以减少文件体积。
3、代码的编译
打开CPP\7zip\Bundles\Format7zF\Format7z.dsw,即可打开7z.dll工程。
我使用的编译器是vs2008,打开dsw文件提示升级,转换后可生成 sln 文件和对应的 vcproj 文件。直接编译。第一次编译,报错:1>LINK : 无法创建 .ILK 文件的映射;正在非增量链接
1>LINK : fatal error LNK1104: 无法打开文件“C:\Program Files\7-Zip\7z.dll”
解决方法:文件占用,编译器权限不够,不能对此文件进行修改,修改生成目标地址,生成到其他地方就可以了。
第二次编译,报错:
1>正在链接...
1>.\Debug\7zCrcOpt.obj : fatal error LNK1107: 文件无效或损坏: 无法在 0x276 处读取
解决方法:删除工程中的asm文件,改由对应的c文件实现,记得将这些c文件的预编译头选项改为“不使用预编译头”。
第三次编译,成功。
4、外部调用通过IDA打开7z.dll可发现其导出函数。
| 函数 | 说明 |
|---|---|
| CreateDecoder | 创建解码器 |
| CreateEncoder | 创建编码器 |
| CreateObject | 创建对象 |
| GetHandlerProperty2 | 获取Handler属性 |
| GetHandlerProperty | 获取Handler属性 |
| GetHashers | 获取 IHasher 对象 |
| GetIsArc | 获取 IsArc 函数地址 |
| GetMethodProperty | 获取解码器属性。传入codecIndex和PROPID,传出PROPVARIANT* |
| GetNumberOfFormats | 获取文件格式的数量。 |
| GetNumberOfMethods | 获取解码器的数量。 |
| SetCaseSensitive | 设置当前文件系统是否大小写敏感,WINDOWS默认不敏感,其他系统默认敏感。 |
| SetCodecs | 传入ICompressCodecsInfo对象,设置外部解码器。 |
| SetLargePageMode | 设置大内存页模式,这种模式可申请更多的内存。 |
------先写这么多,后续更------
来源:CSDN
作者:dAngliaNg
链接:https://blog.csdn.net/dAngliaNg/article/details/103668771