zlib的使用
测试项目目录结构如图
其中zlib源文件放置在libz目录下。
将ZLib源文件编译成静态库
1.在libz-cmake目录下的CMakeLists.txt中编写如下命令,生成静态库。
cmake_minimum_required (VERSION 3.3)
project (z)
file (GLOB_RECURSE SOURCES ${CMAKE_SOURCE_DIR}/libz/*.c)
file (GLOB_RECURSE HEADERS ${CMAKE_SOURCE_DIR}/libz/*.h)
add_library (z STATIC ${SOURCES})
2.test目录中CMakeLists.txt应该链接上述生成的静态库
cmake_minimum_required(VERSION 3.3) #版本
project(mytest) #项目名称 :mytest
add_executable(mytest main.cpp) #生成可执行文件
target_link_libraries(mytest z) #链接上述zlib静态库
3.test目录中main.cpp文件如下
#include <iostream>
#include <stdio.h>
#include "zlib.h"
#include "zutil.h"
#include "zconf.h"
bool CompressBuf(const std::string &strSrcBuf, std::string &strDestBuf)
{
unsigned long nSrcLength = static_cast<unsigned long>(strSrcBuf.length());
unsigned long nDestBufLength = compressBound(nSrcLength);
char *pDestBuf = new char[nDestBufLength];
//初始化
memset(pDestBuf, 0, nDestBufLength * sizeof(char));
int ret = compress((unsigned char *)pDestBuf, &nDestBufLength, (const unsigned char *)strSrcBuf.c_str(), nSrcLength);
std::cout << "after compress : " << nDestBufLength << std::endl;
if (ret != Z_OK)
{
delete[] pDestBuf;
return false;
}
strDestBuf.append(pDestBuf, nDestBufLength);
delete[] pDestBuf;
return true;
}
bool UncompressBuf(const std::string &strSrcBuf, std::string &strDestBuf, size_t nDestBufLength)
{
char *pDestBuf = new char[nDestBufLength];
memset(pDestBuf, 0, nDestBufLength * sizeof(char));
int nPrevDestBufLength = nDestBufLength;
int ret = uncompress((unsigned char *)pDestBuf, (unsigned long *)&nDestBufLength, (const unsigned char *)strSrcBuf.c_str(), strSrcBuf.length());
if (ret != Z_OK)
{
delete[] pDestBuf;
return false;
}
strDestBuf.append(pDestBuf, nDestBufLength);
delete[] pDestBuf;
return true;
}
int main(int argc, char *argv[])
{
std::string str_source = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
std::cout << "str_source len : " << str_source.length() << std::endl;
std::string str_destination = "";
Compress(str_source, str_destination);
std::cout << "str_compress len : " << str_destination.length() << std::endl;
//std::cout << "str_compress : " << str_destination << std::endl;
std::string origin_str = "";
Uncompress(str_destination, origin_str, str_source.length());
std::cout << "str_source : " << origin_str << std::endl;
return 0;
}
最外层的CMakeLists.txt文件中命令如下:
cmake_minimum_required (VERSION 3.3)
project (test_zlib)
include_directories (${PROJECT_SOURCE_DIR}/libz)
include_directories (${PROJECT_SOURCE_DIR}/test)
add_subdirectory(libz-cmake)
add_subdirectory(test)
对于zlib的compress函数,定义如下:
int ZEXPORT compress(unsigned char *dest,
unsigned long *destLen,
const unsigned char *source,
unsigned long sourceLen);
第一个参数:目标buffer,即压缩之后要放入的空间
第二个参数:目标buffer的大小,此处如果小于被压缩数据的长度,该函数会返回Z_BUF_ERROR(-5),所以正确做法如demo中所示:
unsigned long dest_buff_len = compressBound(src_len);
利用compressBound()函数,传入源数据长度,会计算出一个安全边界大小dest_buff_len,将dest_buff_len作为compress()函数第二个参数,传入其地址(compress内部会更改其大小)。
第三个参数:源数据buffer
第四个参数:源数据大小
对于zlib的uncompress函数,定义如下:
int ZEXPORT uncompress(unsigned char *dest,
unsigned long *destLen,
const unsigned char *source,
unsigned long sourceLen)
第一个参数:即解压之后要放入的空间。
对于目标缓冲区,其大小应当大于源数据(即没有压缩之前的数据)空间大小,否则会Z_BUF_ERROR,而太大了,又会浪费空间,所以应当保存一下源数据的空间大小。
第二个参数:即放入空间的大小
第三个参数:要进行解压的数据
第四个参数:要进行解压的数据大小
版权声明:本文为weixin_42734445原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。