简介:QuaZip 是面向 C++ 开发者的开源压缩档案处理库,支持 ZIP 与部分 RAR 格式的读写操作。本资源提供在 Windows 环境下已编译完成的库文件,省去自行编译的繁琐步骤,适合需要快速集成压缩功能的 Qt/C++ 项目使用。压缩包共 29 个文件,约 427KB,包含 17 个头文件、4 个静态库、2 个动态链接库,以及若干 CMake 配置与 pkgconfig 文件,覆盖头文件声明、静态链接与运行时动态加载等完整集成环节。已有 599 人学习下载。借助其中的 lib 与 dll,开发者可直接在 Visual Studio 等环境中配置包含路径与链接器依赖,实现打开、创建、遍历、增删 ZIP 档案内容,并利用内置错误处理机制排查问题,快速完成压缩模块的搭建与调试。
1. QuaZip 编译好的库到底怎么选:从拿到 lib/dll 到跑通第一个解压程序
拿到一个编译好的 QuaZip 库,最怕的不是不会写代码,而是版本对不上。我见过太多人把 dll 往项目目录一丢,编译通过,运行直接崩,报错信息还只有一句“无法定位程序输入点”。QuaZip 本身是 Qt 生态里处理 zip 的老牌库,底层依赖 zlib,编译产物分 lib、dll、a 几种形态,MSVC 和 MinGW 的产物互不通用,Debug 和 Release 也不能混。你手里这份编译好的库,省掉了自己拉源码、配 CMake、找 zlib 的麻烦,但前提是你得先搞清楚自己项目的编译器、架构、Qt 版本和构建模式。这篇笔记按“先对版本、再放文件、后配工程、最后验证”的顺序走一遍,适合刚拿到库不知道怎么塞进项目的 C++ 开发者,也适合被链接错误折腾过一轮、想找一份可复现清单的人。
2. 环境对齐:编译器、架构、Qt 版本一个都不能错
2.1 先确认你手里的库是什么形态
编译好的 QuaZip 库通常包含这几类文件:quazip.lib、quazip.dll(MSVC 动态库),或者libquazip.a、quazip.dll(MinGW 动态库),有时还有quazipd.lib、quazipd.dll这种带 d 后缀的 Debug 版本。头文件一般放在include/quazip/下面,核心是quazip.h、quazipfile.h、JlCompress.h这几个。你拿到压缩包后先别急着往工程里拖,打开目录看一眼文件后缀和命名,这一步决定了后面所有配置。
我一般会先建一个对照表,把库的文件名和它对应的编译条件列出来:
| 文件名特征 | 对应编译器 | 构建模式 | 依赖运行时 |
|---|---|---|---|
| quazip.lib + quazip.dll | MSVC | Release | MSVCRT |
| quazipd.lib + quazipd.dll | MSVC | Debug | MSVCRTD |
| libquazip.a + quazip.dll | MinGW | Release | libgcc |
| libquazipd.a + quazipd.dll | MinGW | Debug | libgcc |
这张表不是绝对的,有些编译产物命名更随意,但规律基本一致:带 d 的是 Debug,不带的是 Release;.lib配 MSVC,.a配 MinGW。如果你在 MSVC 工程里链接了一个 MinGW 编出来的.a,报错会是一堆无法解析的外部符号,而且符号名看起来像乱码,这就是编译器 ABI 不兼容的典型表现。
2.2 检查 Qt 版本和位数
QuaZip 是 Qt 的扩展库,它编译时链接的 Qt 版本必须和你项目用的 Qt 版本一致。Qt 5 和 Qt 6 的 QuaZip 接口有差异,Qt 5 的QString和 Qt 6 的QString在二进制层面也不完全兼容。你可以在 Qt Creator 的“关于”里看版本号,或者命令行执行:
qmake -query QT_VERSION qmake -query QT_INSTALL_PREFIX第一条输出 Qt 版本,第二条输出 Qt 安装路径。如果库是别人用 Qt 5.15.2 编的,你项目用的是 Qt 6.5,那大概率链接失败或者运行崩溃。位数也要对:32 位 Qt 只能配 32 位库,64 位配 64 位。Windows 上可以用dumpbin /headers quazip.dll | findstr machine看 dll 的架构,输出x64就是 64 位,x86就是 32 位。MinGW 环境下用objdump -f quazip.dll也能看到类似信息。
2.3 确认 zlib 依赖是否已经打包
QuaZip 底层依赖 zlib,编译好的库有两种情况:一种是静态链接了 zlib,你只需要 QuaZip 自己的 lib/dll;另一种是动态链接 zlib,你还需要额外放zlib1.dll或zlib.lib。判断方法很简单,用 Dependency Walker 或者dumpbin /dependents quazip.dll看依赖列表。如果输出里有zlib1.dll,那运行目录必须同时放这个文件,否则程序启动就报缺少 dll。我一般会先把quazip.dll和可能需要的zlib1.dll一起复制到可执行文件目录,再开始配工程。
3. 文件落位:头文件、lib、dll 分别放哪里
3.1 目录结构建议
不要把所有文件混在项目根目录。我习惯在项目旁边建一个third_party/quazip/目录,里面再分include、lib、bin三个子目录:
third_party/ └── quazip/ ├── include/ │ └── quazip/ │ ├── quazip.h │ ├── quazipfile.h │ └── JlCompress.h ├── lib/ │ ├── quazip.lib │ └── quazipd.lib └── bin/ ├── quazip.dll └── quazipd.dll这样做的好处是工程配置里路径清晰,换一台机器或者换一个 Qt 版本时,只需要替换third_party/quazip整个目录,不用去翻项目里散落的文件。头文件目录里保留quazip这一层,是因为代码里通常写#include <quazip/quazip.h>,如果你把头文件直接放在include/下,包含路径就要改,容易和别的库冲突。
3.2 在 qmake 工程里配置
如果你用的是 qmake,在.pro文件里加这几行:
# 头文件搜索路径,指向 include 的上一级 INCLUDEPATH += $$PWD/third_party/quazip/include # 链接库搜索路径,区分 Debug 和 Release CONFIG(debug, debug|release) { LIBS += -L$$PWD/third_party/quazip/lib -lquazipd } else { LIBS += -L$$PWD/third_party/quazip/lib -lquazip } # 把 dll 复制到输出目录,避免手动拷贝 QMAKE_POST_LINK += $$quote(cmd /c copy /y $$PWD/third_party/quazip/bin\\quazip.dll $$OUT_PWD\\release\\)INCLUDEPATH让编译器找到头文件,LIBS里的-L指定 lib 所在目录,-l指定库名,注意 MSVC 下-lquazip会自动找quazip.lib,MinGW 下会找libquazip.a。QMAKE_POST_LINK是构建后自动复制 dll,省得每次手动拖。这里有个细节:$$OUT_PWD是构建输出目录,Release 构建时 dll 要放到release子目录,Debug 放到debug子目录,如果你只写了一个路径,另一种构建模式运行时就会找不到 dll。
3.3 在 CMake 工程里配置
CMake 工程更常见,配置方式如下:
# 头文件目录 target_include_directories(YourApp PRIVATE ${CMAKE_SOURCE_DIR}/third_party/quazip/include ) # 链接库,按构建类型区分 target_link_libraries(YourApp PRIVATE $<$<CONFIG:Debug>:${CMAKE_SOURCE_DIR}/third_party/quazip/lib/quazipd.lib> $<$<CONFIG:Release>:${CMAKE_SOURCE_DIR}/third_party/quazip/lib/quazip.lib> ) # 构建后复制 dll add_custom_command(TARGET YourApp POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/third_party/quazip/bin/quazip.dll $<TARGET_FILE_DIR:YourApp> )target_include_directories指定头文件路径,target_link_libraries用生成器表达式按 Debug/Release 分别链接不同的 lib,add_custom_command在每次构建后把 dll 复制到可执行文件旁边。如果你用的是 MinGW 生成器,链接的应该是.a文件,路径改成libquazip.a或libquazipd.a。CMake 里不要用link_directories这种全局设置,容易污染其他 target,用target_link_libraries直接写全路径更稳。
4. 避坑排查:链接失败、运行崩溃、中文乱码的常见原因
4.1 现象:编译报“无法解析的外部符号”
原因通常是编译器不匹配或者 Debug/Release 混用。MSVC 工程链接了 MinGW 的.a,或者 Release 构建链接了带 d 的 Debug 库,都会出现一堆unresolved external symbol。符号名里如果带__imp_前缀,说明链接的是动态库的导入库,但 dll 没找到或者导入库和 dll 不配对。
解决方法是先确认编译器:Qt Creator 左下角套件里看是 MSVC 还是 MinGW。然后确认构建模式:左下角构建按钮旁边选的是 Debug 还是 Release。最后检查.pro或CMakeLists.txt里链接的库名是否和构建模式一致。我一般会在.pro里用CONFIG(debug, debug|release)自动切换,避免手动改来改去。
4.2 现象:编译通过,运行报“找不到 quazip.dll”
原因是 dll 不在可执行文件的搜索路径里。Windows 下 exe 启动时会在当前目录、系统目录、PATH 环境变量目录里找 dll,你的quazip.dll如果只放在third_party/quazip/bin下,exe 是找不到的。
解决办法有两个:一是把 dll 复制到 exe 同目录,用前面 qmake 的QMAKE_POST_LINK或 CMake 的add_custom_command自动做;二是把 dll 所在目录加到 PATH 里,但这种方法在部署时容易忘,不推荐。我习惯用自动复制,构建完直接运行,不用管 dll 在哪。
4.3 现象:程序启动时报“无法定位程序输入点”
原因是 dll 和 lib 版本不匹配,或者 dll 依赖的 Qt 库版本不对。比如你用 Qt 5.15 的 lib 链接,但运行目录里放的是 Qt 5.12 的Qt5Core.dll,QuaZip 调用的某个 Qt 函数在新版本里签名变了,就会报输入点找不到。
解决办法是确保quazip.dll和项目使用的 Qt dll 来自同一个 Qt 安装。可以用dumpbin /dependents quazip.dll看它依赖哪些 Qt dll,然后检查这些 dll 的版本是否和项目一致。最稳妥的做法是直接把 Qt 安装目录下的bin加到 PATH 最前面,或者用windeployqt工具自动收集依赖。
4.4 现象:解压出来的中文文件名乱码
原因是 QuaZip 默认按本地编码处理文件名,而 zip 文件里的文件名可能是 UTF-8 或 GBK。Windows 下中文系统默认 GBK,如果 zip 是 Linux 下打的包,文件名通常是 UTF-8,直接解压就会乱码。
解决办法是在调用 QuaZip 之前设置编码。QuaZip 提供了QuaZip::setFileNameCodec方法:
QuaZip zip("archive.zip"); // 如果 zip 是 UTF-8 编码的文件名,显式设置 zip.setFileNameCodec("UTF-8"); if (!zip.open(QuaZip::mdUnzip)) { qDebug() << "打开失败:" << zip.getZipError(); return; }setFileNameCodec的参数是编码名称,常见的有UTF-8、GBK。如果你不确定 zip 里文件名的编码,可以先不设置,看解压出来的名字是否正常,不正常再试另一种。我一般会在打开 zip 后先读一个文件名,判断是否包含乱码字符,再决定用哪种编码。
4.5 现象:Debug 下正常,Release 下崩溃
原因是 Debug 和 Release 的运行时库不兼容,或者 Release 下某些断言被优化掉了。MSVC 的 Debug 用MSVCRTD,Release 用MSVCRT,如果链接的 QuaZip 库是 Debug 版但项目是 Release,运行时库冲突会导致堆损坏。
解决办法是严格区分 Debug 和 Release 的库文件,.pro里用CONFIG(debug, debug|release)自动切换,CMake 里用$<$<CONFIG:Debug>:...>生成器表达式。不要图省事只配一个版本,否则换构建模式就翻车。
5. 验证跑通:写一个最小解压程序确认库能用
5.1 最小验证代码
配置完成后,别急着往大项目里集成,先写一个最小程序验证库能正常编译、链接、运行。下面这段代码打开一个 zip 文件,列出里面的文件名,然后解压第一个文件:
#include <QCoreApplication> #include <QDebug> #include <quazip/quazip.h> #include <quazip/quazipfile.h> int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); // 替换成你本地实际的 zip 文件路径 QuaZip zip("test.zip"); zip.setFileNameCodec("UTF-8"); if (!zip.open(QuaZip::mdUnzip)) { qDebug() << "打开 zip 失败,错误码:" << zip.getZipError(); return -1; } // 列出所有文件名 QStringList files = zip.getFileNameList(); qDebug() << "zip 内文件列表:" << files; // 解压第一个文件到当前目录 if (!files.isEmpty()) { QuaZipFile file(&zip); if (file.open(QIODevice::ReadOnly)) { QByteArray data = file.readAll(); qDebug() << "第一个文件大小:" << data.size() << "字节"; file.close(); } else { qDebug() << "打开文件失败:" << file.getZipError(); } } zip.close(); return 0; }这段代码只依赖 QuaZip 和 QtCore,不涉及 GUI,适合快速验证。QuaZip::mdUnzip表示以解压模式打开,getFileNameList返回文件名列表,QuaZipFile用来读单个文件。如果你编译时提示找不到quazip/quazip.h,说明INCLUDEPATH没配对;如果链接时提示找不到quazip相关符号,说明LIBS没配对;如果运行时报错,看getZipError返回的错误码,常见的有ZIP_ER_NOZIP(不是 zip 文件)、ZIP_ER_OPEN(文件打不开)。
5.2 验证清单
跑通最小程序后,按下面这张清单逐项确认,避免后面集成到大项目里再返工:
| 检查项 | 验证方法 | 通过标准 |
|---|---|---|
| 头文件路径 | 编译无“找不到头文件”错误 | #include <quazip/quazip.h>能解析 |
| lib 链接 | 链接无“无法解析的外部符号” | 生成 exe 无链接错误 |
| dll 加载 | 运行无“找不到 dll”弹窗 | 程序正常启动 |
| 解压功能 | 能列出文件名并读取内容 | 输出文件列表和字节数 |
| 中文编码 | 中文文件名不乱码 | 文件名显示正常 |
| Debug/Release | 两种模式都能跑 | 切换构建模式后重新验证 |
我一般会在 Debug 和 Release 下各跑一遍这个最小程序,确认两种模式都没问题,再往正式项目里集成。有一次偷懒只测了 Debug,Release 下链接了错误的库,上线后直接崩,从那以后我每次拿到新的第三方库都强制走一遍这个清单。
5.3 部署时的注意事项
正式部署时,除了quazip.dll,还要确认zlib1.dll和 Qt 相关的 dll 都在。用windeployqt可以自动收集 Qt 依赖:
windeployqt --release --no-translations YourApp.exe这条命令会把Qt5Core.dll、Qt5Gui.dll等复制到 exe 同目录,但不会复制quazip.dll和zlib1.dll,这两个需要手动放。我习惯在部署脚本里加一行复制命令,确保每次打包都不遗漏。另外,如果目标机器没有安装 Visual C++ 运行时,还需要把msvcp140.dll、vcruntime140.dll一起带上,或者让用户安装对应的运行时包。
希望帮到你。
本文还有配套的精品资源,点击获取