標籤:參考 cts fatal 組態管理 作用 asm 簡單的 project 備忘
手上有個小程式需要通過HTTP協議通訊,選擇了出名的libcurl作為支援庫。由於網上的教程多是命令列編譯,本人記性不好,比較討厭記住一堆命令,因此折騰了一天通過VS對libcurl和zlib進行了編譯。下面就將編譯過程記錄下作為備忘。
一、環境及庫版本介紹
win10 64位、VS_professional_2013_with_update_5、curl-7.54.1、zlib-1.2.11
二、目的
產生libcurl靜態庫,並支援在xp下使用
三、開始
1、編譯zlib
從http://www.zlib.net/下載zlib-1.2.11並解壓;進入目錄zlib-1.2.11\contrib\vstudio\vc12開啟工程,選擇zlibstat項目,設定屬性->releasewithoutasm->常規->平台工具集->Visual Studio 2013 - Windows XP (v120_xp),字元集本人項目全是unicode,因此這個地方也設定為unicode。如果選擇release編譯的話需要先編譯asm代碼,可以參考之前我寫的zlib教程(1、lib-1.2.8的編譯 從http://www.zlib.net/下載zlib-1.2.8.tar.gz,解壓到目錄zlib-1.2.8; 用vs2008命令列進入zlib-1.2.8\contrib\masmx86目錄,執行bld_ml32.bat; 進入目錄zlib-1.2.8\contrib\vstudio,編譯 4、靜態連結庫zlibstat.lib使用 引入標頭檔zlib.h,加入 #pragma comment(lib, "zlibstat.lib"),在使用時提示 error LNK2019: 無法解析的外部符號 _inflateEnd,error LNK2019: 無法解析的外部符號 _inflate,等時讓人很鬱悶,研究多時才發現需要在引入標頭檔zlib.h前加上#define ZLIB_WINAPI,大爺的。)zlib靜態連結庫的使用只需要2個標頭檔,zconf.h和zlib.h
2、編譯libcurl
從https://curl.haxx.se/libcurl/下載libcurl-7.54.1並解壓,進入目錄curl-7.54.1\projects\Windows\VC12開啟工程,選擇libcurl項目,通過組態管理員建立配置,為了通俗易懂,我起名LIB Release - DLL WIN SSPI - DLL WinIDN - lib zlib以LIB Release - DLL Windows SSPI - DLL WinIDN為模板,加入sspi可以支援https,winidn的作用我還不知道。
選擇libcurl項目,設定屬性->LIB Release - DLL WIN SSPI - DLL WinIDN - lib zlib->常規->平台工具集->Visual Studio 2013 - Windows XP (v120_xp),字元集unicode。C/C++->前置處理器->前置處理器定義增加HAVE_ZLIB_H;HAVE_LIBZ;ZLIB_WINAPI。C/C++->常規->附加元件封裝含目錄 增加zlib.h和zconf.h所在目錄(建議把上步產生的lib、zlib.h和zconf.h檔案拷貝到一個專用的檔案夾裡面)庫管理器->常規 設定附加庫目錄和附加依賴項zlibstat.lib(上步產生的lib檔案名稱)。
編譯,這時會出現libcurl.res : fatal error LNK1241: 已指定資源檔 zlibstat.lib(zlib.res)錯誤,原因是libcurl項目和zlib項目都添加了資源version,解決辦法就是在上步編譯zlib時開啟方案總管把zlib.rc移除再編譯。再次編譯libcurl,搞定
四、libcurl的使用
引入標頭檔,加入CURL_STATICLIB宏
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"wldap32.lib")
#pragma comment(lib,"Crypt32.lib")
#pragma comment(lib,"Normaliz.lib")
#pragma comment(lib,"libcurl.lib")
至於編譯時間該用md mt mdd mtd 請自行統一即可
網上教程一大堆,我這裡只記錄些資料比較少的內容。
有的網頁在傳輸時不管用戶端是否支援壓縮都是經過壓縮傳輸的,直接從web擷取網頁的原始碼後,得到的是壓縮後代碼,我們可以自己解碼,也可以讓libcurl來自動完成,上述所寫加入zlib就是為了可以自動解碼。
通過curl_easy_setopt(curl_, CURLOPT_ACCEPT_ENCODING, "gzip");可以完成自動解碼。除了gzip還有其他編碼方式,本人記性實在不好,記不住別的都有啥。
libcurl的使用最簡單的步驟(下面開始抄襲別人總結的內容,在此謝謝原作者):
CURL* curl=curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "http://www.baidu.com");
curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_global_cleanup();
關於多線程,應該在程式最開始的地方 curl_global_init, 然後再建立各個線程,在各個線程中用 curl_easy_init來建立curl 的 handle,然後針對這個handle用 curl_easy_setopt(handle, xxx, xxx) 設定傳輸相關的各種參數,最後用 cur_easy_perform(handle)來執行動作,傳輸結束後,最後調用 curl_easy_cleanup(handle) 來釋放,然後結束線程在程式的主線程中,等所有線程都結束後,在程式退出前,調用 curl_global_cleanup來結束 libcurl.
libcurl-7.54.1附加zlib1.2.11的編譯