C++ 使用zlib开源库的minizip解压缩文件及文件夹

首先 GitHub 上下载 zlib 的发行版本进行编译;

如果出现 zlib报“LNK2001:无法解析的外部符号”错误 的情况,是因为编译zlib(dll)的工程默认有预处理器定义ZLIB_WINAPI,ZEXPORT在zconf.h中的定义为WINAPI:

/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include 
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif

#define WINAPI      __stdcall
所以,zlib(dll)的导出函数调用约定为__stdcall,和zlib(dll)的导入函数调用约定__cdecl不一致。

针对zlib编译dll文件编译出错,有以下两种解决办法:

1. 在zlivc工程中去掉预处理器定义ZLIB_WINAPI(预处理定义:vs工程属性->C/C++->预处理器)

去掉该定义后,宏定义ZEXPORT在zconf.h文件中实际定义如下:

#ifndef ZEXPORT
#  define ZEXPORT
#endif
// 所以导出函数unzGoToNextFile
extern int ZEXPORT unzGoToNextFile (unzFile  file)

// 等价于
extern int unzGoToNextFile (unzFile  file)

// 也等价于(vs默认是__cdecl函数调用约定)
extern int __cdecl unzGoToNextFile (unzFile  file)

所以在新的工程中导入zlib相关的库文件和dll文件后,编译dll的工程和引入dll的工程的函数调用约定均为__cdecl方式,导出函数能够正确解析了,编译自然就通过了。由上宏定义注释可知,标准编译ZLIB1.DLL是没有ZLIB_WINAPI预处理定义的,函数调用约定也是__cdecl,所以这里推荐该解决方案。

2. 在引入zlib工程中添加预处理器定义ZLIB_WINAPI

在引入dll工程中添加ZLIB_WINAPI定义后,宏定义ZEXPORT在zconf.h文件中实际定义如下:

#define ZEXPORT WINAPI

#define WINAPI  __stdcall

与导出zlib的dll工程均为__stdcall函数调用约定,编译也能顺利通过。

 

zlibHelper.h

#pragma once
#include 
#include 
#include "zip.h"
#include "unzip.h"
#include "zlib.h"

class CZlibHelper
{
public:
	CZlibHelper();
	~CZlibHelper();
	//主要的压缩函数
	//将文件添加到zip文件,若zip文件已存在,则覆盖该文件
	static bool CreateZipfromDir(const std::string& dirpathName, const std::string& zipfileName, const std::string& parentdirName);
	//将文件添加到zip文件,若该zip文件不存在则创建一个zip文件
	static bool CreateZipfromDir2(const std::string& dirpathName, const std::string& zipfileName, const std::string& parentdirName);
	//主要的解压函数
	static bool UnzipFile(const std::string& strFilePath, const std::string& strTempPath);

private:
	//添加文件和文件夹到
	static bool AddfiletoZip(zipFile zfile, const std::string& fileNameinZip, const std::string& srcfile);

	static bool CollectfileInDirtoZip(zipFile zfile, const std::string& filepath, const std::string& parentdirName);
	//字符串 字符替换功能函数
	static std::string& replace_all(std::string& str, const std::string& old_value, const std::string& new_value);
	//创建多级目录
	static bool CreatedMultipleDirectory(const std::string& direct);
};

zlibHelper.cpp

你可能感兴趣的:(zlib,C++,zlib,minizip)