開放、平等、協(xié)作、快速、分享
代碼git地址:https://github.com/criticalstack/libevhtp
1.Visual Studio 必須 筆者用的是VS2019
2.Libevent2庫(kù) 必須 git地址:https://github.com/libevent/libevent,libevent的windows版本編譯相對(duì)簡(jiǎn)單)
3.CMake 必須 網(wǎng)上可下載,如果網(wǎng)上地址太慢。到 這里 下載
4.OpenSSL 可選 網(wǎng)上下載,也可以通過(guò)源代碼編譯
5.pthreads 可選 VS的插件管理里面安裝
6.onig(regex 可選 git地址:https://github.com/kkos/oniguruma
說(shuō)明:圖中需要編譯的庫(kù)都會(huì)在源代碼里面提供,必須具備 1 和 3
按照原作者說(shuō)明,采用cmake + “MSYS Makefiles“ 來(lái)進(jìn)行編譯,這種方式我嘗試過(guò),沒(méi)有成功。最終采用”Visual Studio“的方式來(lái)編譯。
1.打開代碼根目錄(包含CMakeLists.txt文件),創(chuàng)建build目錄
2.通過(guò)DOS(或者其他SHELL工具)進(jìn)入到代碼目錄,進(jìn)入build目錄
3.執(zhí)行命令 cmake -DLIBEVENT_INCLUDE_DIR=..packageincludelibevent-2.1.11 -DONIGURUMA_INCLUDE_DIR=..packageincludeoniguruma-6.9.3 ..
4.看到提示顯示創(chuàng)建失敗,提示缺少 LIBEVENT_THREAD,這是因?yàn)閘ibevent庫(kù)編譯windows版本時(shí)沒(méi)有提供出這個(gè)庫(kù),具體原因未知..
5.轉(zhuǎn)到根目錄下的cmake文件夾下,打開options.cmake文件,將”option (EVHTP_DISABLE_EVTHR "Disable evthread support" OFF)“ 這行的 OFF 改為 ON
6.繼續(xù)執(zhí)行步驟3代碼,會(huì)提示一些錯(cuò)誤,大概意思就時(shí)文件已經(jīng)被包含過(guò),不過(guò)不影響,現(xiàn)在我們查看build目錄下,發(fā)現(xiàn)已經(jīng)有了VS的項(xiàng)目文件libevhtp.sln
7.雙擊打開libevhtp.sln,選擇evhtp這個(gè)工程進(jìn)行編譯,會(huì)提示如下信息:”無(wú)法解析的外部符號(hào) __imp_bind,該符號(hào)在函數(shù) evhtp_bind_sockaddr 中被引用“等信息,這是由于未配置windows下的WS2_32.Lib庫(kù),添加再配置項(xiàng)里添加這個(gè)依賴
8.重新編譯發(fā)現(xiàn)生成發(fā)現(xiàn)沒(méi)有報(bào)錯(cuò),成功生成了evhtp.dll。但這里我發(fā)現(xiàn)另外個(gè)問(wèn)題,沒(méi)有對(duì)應(yīng)的lib生成。
9.查看對(duì)應(yīng)的接口定義,是由EVHTP_EXPORT這個(gè)宏導(dǎo)出,這個(gè)宏定義在build目錄下的include下的config.h的文件中。在windows下,這個(gè)宏定義為空。
#ifndef EVHTP_NEED_EXPORT #if (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER || defined __clang__ # define EVHTP_EXPORT __attribute__ ((visibility("default"))) # else # define EVHTP_EXPORT __declspec(dllimport) # endif #else # if (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER || defined __clang__ # define EVHTP_EXPORT # else # define EVHTP_EXPORT __declspec(dllexport) # endif #endif
修改后的config.h開頭定義如下,重新定義一個(gè)是否導(dǎo)出的宏 EVHTP_NEED_EXPORT,將這宏放到預(yù)處理定義里,并刪除原來(lái)的 EVHTP_EXPORT宏。重新編譯后,包含evhtp.lib及evhtp.dll文件
新建一個(gè)工程,利用evhtp庫(kù)創(chuàng)建一個(gè)http服務(wù)器,看是否成功。代碼如下:
1 // main.cpp: 主程序入口 2 // 3 #include4 #include "evhtp.h" 5 #include6 7 evhtp_t* g_htp; 8 9 #define REGISTER_HTP_CB(path, cb, arg) evhtp_set_cb(g_htp, path, cb, arg) 10 11 void HtpCallBack(evhtp_request_t* req, void* a) 12 { 13 std::cout << "recv a command" << std::endl; 14 evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "application/json", 0, 0)); 15 evbuffer_add(req->buffer_out, "hello, evhtp! success.", sizeof("hello, evhtp! success.")); 16 evhtp_send_reply(req, EVHTP_RES_OK); 17 } 18 19 int main(int argc, const char* argv[]) 20 { 21 WSADATA wsaData; 22 WSAStartup(MAKEWORD(1, 1), &wsaData); 23 24 evbase_t* evbase = event_base_new(); 25 g_htp = evhtp_new(evbase, NULL); 26 evhtp_use_threads_wexit(g_htp, NULL, NULL, 16, NULL); 27 28 REGISTER_HTP_CB("/api", HtpCallBack, nullptr); 29 30 evhtp_bind_socket(g_htp, "0.0.0.0", 8080, 1024); 31 32 event_base_loop(evbase, 0); 33 34 WSACleanup(); 35 36 return 0; 37 } |
編譯后,運(yùn)行程序。提示 無(wú)法定位程序點(diǎn)輸入點(diǎn) evhtp_use_threads_wexit 。查找該函數(shù)定義在evhtp.c文件中,不過(guò)該函數(shù)是否編譯由 EVHTP_DISABLE_EVTHR 宏來(lái)控制,在上面步驟5里面,我們將這個(gè)編譯選型設(shè)置為ON,所以導(dǎo)致頭文件中由接口定義,但是卻沒(méi)有實(shí)現(xiàn)。
修改build/include目錄下的config文件中將 #define EVHTP_DISABLE_EVTHR代碼注釋掉,注意可能存在多行。重新編譯我們的evhtp庫(kù),會(huì)提示找不到pthread.h找不到,將VS中NuGet找到pthread的庫(kù)安裝即可。
如果提示timespec重定義錯(cuò)誤,在預(yù)處理宏中加上 HAVE_STRUCT_TIMESPEC 定義
編譯成功運(yùn)行工程,通過(guò)web頁(yè)面發(fā)送請(qǐng)求,成功。通過(guò)ProcessExplorer工具查看,程序也是有17個(gè)線程。遇到過(guò)沒(méi)編譯好,只有一個(gè)線程情況。
附上我編譯后的源代碼地址:https://github.com/kswangxing/evhtp_win
里面包含編譯后代碼。
編譯環(huán)境:VS2019 64位
24小時(shí)免費(fèi)咨詢
請(qǐng)輸入您的聯(lián)系電話,座機(jī)請(qǐng)加區(qū)號(hào)