zlib库的编译及使用
* 打开网址http://zlib.net/ 下载zlib源码,
* 解压压缩包,进入目录:C:\Users\Administrator\Desktop\zlib-1.2.11\zlib-1.2.11\contrib\vstudio\vc12,打开zlibvc.sln工程。
32位编译有以下问题:
** match686.obj : error LNK2026: 模块对于 SAFESEH 映像是不安全的。
** 解决:
** 使用zlib开源库在VS2013中开发,但是在使用uncompress函数进行解压缩过程中遇到了内存崩溃现象。
** 解决:
用c编译方式取代汇编方式,在zlib源码的zlibvc工程中,分为2步:
1.工程属性->预处理器,去掉 ASMINF 定义,这样就可以屏蔽掉汇编模块:
2.
打开zlib-1.2.11\contrib\masmx86下面的汇编文件inffas32.asm,将里面_inflate_fast全部替换成其他任意函数名,再次编译。
修改为:_inflate_fast1
64位编译有以下问题:
** 解决
修改为:cd ..\..\masmx64bld_ml64.bat
*** 库目录修改:
32位导出的函数名称与64位导出的函数名称有区别,这可能是是使用zlib 的lib库进行静态连接时,32位需要追加ZLIB_WINAPI
否则会报error LNK2019 错误:
32位导出的函数名称与64位导出的函数名称有区别如下图:
32位:
64位:
*********zlib库的使用:
工程配置,32位工程必须追加加入宏定义 :ZLIB_WINAPI,64位随意。
***** 测试代码如下:
// zlib.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <windows.h>
//extern "C"{
#include "zlib.h"
//}
//#pragma comment(lib, "32lib/zlibwapi.lib")
//------------------------------------------------------------------------测试函数---------------------------------------------------------------------------------------------------------
// 包头长度大约为192个字节
int g_nPackHead[] = {
10, 62, 84, 74, 96, 70, 77, 149, 237, 164, 71, 72, 229, 245, 233, 47, 101, 155, 252, 189, 94, 69, 9, 6, 72, 69, 241, 182, 21, 70, 216, 101, 150, 247, 133, 81, 146, 66, 31, 35, 106, 53, 133
, 66, 248, 124, 16, 224, 122, 80, 28, 61, 8, 193, 124, 122, 79, 111, 4, 88, 98, 1, 79, 111, 0, 8, 0, 5, 54, 198, 32, 239, 45, 234, 2, 182, 47, 188, 79, 111, 0, 0, 16, 225, 106, 69
, 53, 1, 146, 72, 81, 82, 84, 83, 16, 235, 10, 72, 5, 4, 76, 90, 146, 181, 28, 31, 153, 222, 249, 16, 226, 37, 3, 18, 249, 82, 84, 83, 16, 249, 241, 76, 120, 2, 243, 32, 239, 49, 33
, 46, 115, 125, 78, 0, 0, 1, 37, 16, 232, 33, 4, 16, 216, 48, 56, 56, 56, 16, 237, 164, 81, 37, 82, 21, 199
, 111, 2, 248, 98, 3, 122, 80, 28, 61, 8, 193, 72, 5, 53, 224, 122, 80, 68, 61, 8, 193, 124, 122, 79, 111, 4, 88, 98, 1, 79, 111
};
const char* p5Price = "3215565665";
const char * pLastPrice = "123%06d+1811%d;";
int g_ncin = 0;
int g_nLevel = 0;
#define TEMP_MAX 65536
//#define TEMP_MAX 200
#if 1
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "输入:\t 0.订阅一条最新价 \t1.订阅五档行情\t2.订阅五档行情/一条最新价\t3.订阅五档行情/2条最新价...以此类推,最大值为500,默认值20" << std::endl;
std::cout << "输入压缩等级(1-9):\t 1最小压缩,9为最大压缩,默认5" << std::endl;
std::cout << "输入格式:\t条数+压缩等级,如251,25条行情,1级压缩" << std::endl;
//unsigned char* testchar = new unsigned char[65536];
unsigned char testchar[TEMP_MAX];
unsigned char testchar1[TEMP_MAX];
while (true)
{
g_ncin = 1;
g_nLevel = 5;
memset(testchar, 0x00, TEMP_MAX);
unsigned long nHeadSize = (sizeof(g_nPackHead) / sizeof(int));
unsigned long Offset = nHeadSize;
for (unsigned long i = 0; i < nHeadSize; i++)
{
testchar[i] = g_nPackHead[i];
}
int indata;
std::cin >> indata;
g_ncin = indata / 10;
g_nLevel = indata % 10;
std::cout << "............................................................................................" << std::endl;
if ((g_ncin < 0) || (g_ncin >500))
{
g_ncin = 20;
}
if ((g_nLevel < 0) || (g_nLevel > 9))
{
g_nLevel = 5;
}
if (0 == g_ncin)
{
strcat_s((char*)(testchar + Offset), 256, p5Price);
Offset += strlen(p5Price);
}
else
{
for (int i = 0; i <= g_ncin - 1; i++)
{
char x[65536];
sprintf_s(x, sizeof(x), pLastPrice, i + 1, i + 2);
strcat_s((char*)(testchar + Offset), 128, x);
Offset += strlen(x);
}
// 追加五档行情
if (g_ncin > 1)
{
strcat_s((char*)(testchar + Offset), 256, p5Price);
Offset += strlen(p5Price);
}
}
unsigned long len = Offset;
printf("压缩前src_len=%lu\tsrc: %s\n", Offset, (char*)(testchar + nHeadSize));
unsigned char dest[TEMP_MAX]; memset(dest, 0x00, TEMP_MAX);
unsigned long destLen = TEMP_MAX;
//int tt = GetTickCount();
//const int count = 10 * 100 * 100;
//for (int t = 0; t < count; t++)
//{
destLen = TEMP_MAX;
memset(dest, 0x00, sizeof(dest));
//压缩
//compressBound(len);
//功能和compress函数一样,多了一个参数可以指定压缩质量和压缩数度之间的关系(1-9)。要想得到高的压缩比就要多花时间
if (Z_OK == compress2(dest, &destLen, testchar, len, g_nLevel))
{
printf("压缩后dest_len=%d\t dest: %s\n", destLen, dest);
}
else
{
printf("压缩失败\n");
}
//}
//printf("%d只股票%d次数耗时耗时======= %ld ms\n\n", g_ncin,count,GetTickCount() - tt);
memset(testchar1, 0x00, sizeof(testchar1));
unsigned long src_len = TEMP_MAX;
//解压缩
if (Z_OK == uncompress2(testchar1, &src_len, dest, &destLen))
//if (Z_OK)
//if (Uncompress(testchar, &src_len, dest, destLen) == 0)
{
printf("解压后src_len=%d\tsrc: %s\n", src_len, (char*)(testchar1 + nHeadSize));
}
else
{
printf("解压缩失败\n");
}
int r = memcmp(testchar, testchar1, src_len);
if (0 == r)
{
printf("destLen=%d\t srclen=%d\t 压缩率%f%%\n\n", destLen, src_len, (double)(destLen * 100) / (double)(src_len));
}
else
{
printf("解压缩后的数据与原数据不一致\n\n");
}
}
system("pause");
return 0;
}
#else
int _tmain(int argc, _TCHAR* argv[])
{
/*原始数据*/
unsigned char strsrc[] = "这些是测试数据。123456789 abcdefghigklmnopqrstuvwxyz\n\t\0abcdefghijklmnopqrstuvwxyz\n"; //包含\0字符
unsigned char buf[1024] = {0};
unsigned char strdst[1024] = {0};
unsigned long srclen = sizeof(strsrc);
unsigned long buflen = sizeof(buf);
unsigned long dstlen = sizeof(strdst);
int i;
// FILE * fp;
printf("源串:");
for (i = 0; i < srclen; ++i)
{
printf("%c", strsrc[i]);
}
printf("原串长度为:%ld\n", srclen);
printf("字符串预计算长度为:%ld\n", compressBound(srclen));
//压缩
//compress(buf, &buflen, strsrc, srclen);
int ret = compress2(buf, &buflen, strsrc, srclen,9);
printf("压缩后实际长度为:%ld\n", buflen);
//解压缩
uncompress(strdst, &dstlen, buf, buflen);
printf("目的串:");
for (i = 0; i < dstlen; ++i)
{
printf("%c", strdst[i]);
}
return 0;
}
#endif