zlib庫的編譯及使用

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

複製代碼

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章