工做須要搭建基於C++的http服務,最後選擇使用evhtp。在linux下的編譯參考readme便可。如今重點來講下windows下的編譯過程。linux
代碼git地址:https://github.com/criticalstack/libevhtpios
1.Visual Studio 必須 筆者用的是VS2019git
2.Libevent2庫 必須 git地址:https://github.com/libevent/libevent,libevent的windows版本編譯相對簡單)github
3.CMake 必須 網上可下載,若是網上地址太慢。到 這裏 下載web
4.OpenSSL 可選 網上下載,也能夠經過源代碼編譯json
5.pthreads 可選 VS的插件管理裏面安裝windows
6.onig(regex 可選 git地址:https://github.com/kkos/onigurumaapi
說明:圖中須要編譯的庫都會在源代碼裏面提供,必須具有 1 和 3服務器
按照原做者說明,採用cmake + 「MSYS Makefiles「 來進行編譯,這種方式我嘗試過,沒有成功。最終採用」Visual Studio「的方式來編譯。app
1.打開代碼根目錄(包含CMakeLists.txt文件),建立build目錄
2.經過DOS(或者其餘SHELL工具)進入到代碼目錄,進入build目錄
3.執行命令 cmake -DLIBEVENT_INCLUDE_DIR=..\package\include\libevent-2.1.11 -DONIGURUMA_INCLUDE_DIR=..\package\include\oniguruma-6.9.3 ..
4.看到提示顯示建立失敗,提示缺乏 LIBEVENT_THREAD,這是由於libevent庫編譯windows版本時沒有提供出這個庫,具體緣由未知..
5.轉到根目錄下的cmake文件夾下,打開options.cmake文件,將」option (EVHTP_DISABLE_EVTHR "Disable evthread support" OFF)「 這行的 OFF 改成 ON
6.繼續執行步驟3代碼,會提示一些錯誤,大概意思就時文件已經被包含過,不過不影響,如今咱們查看build目錄下,發現已經有了VS的項目文件libevhtp.sln
7.雙擊打開libevhtp.sln,選擇evhtp這個工程進行編譯,會提示以下信息:」沒法解析的外部符號 __imp_bind,該符號在函數 evhtp_bind_sockaddr 中被引用「等信息,這是因爲未配置windows下的WS2_32.Lib庫,添加再配置項裏添加這個依賴
8.從新編譯發現生成發現沒有報錯,成功生成了evhtp.dll。但這裏我發現另外個問題,沒有對應的lib生成。
9.查看對應的接口定義,是由EVHTP_EXPORT這個宏導出,這個宏定義在build目錄下的include下的config.h的文件中。在windows下,這個宏定義爲空。
#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開頭定義以下,從新定義一個是否導出的宏 EVHTP_NEED_EXPORT,將這宏放到預處理定義裏,並刪除原來的 EVHTP_EXPORT宏。從新編譯後,包含evhtp.lib及evhtp.dll文件
新建一個工程,利用evhtp庫建立一個http服務器,看是否成功。代碼以下:
1 // main.cpp: 主程序入口 2 // 3 #include <iostream> 4 #include "evhtp.h" 5 #include <WinSock2.h> 6 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 }
編譯後,運行程序。提示 沒法定位程序點輸入點 evhtp_use_threads_wexit 。查找該函數定義在evhtp.c文件中,不過該函數是否編譯由 EVHTP_DISABLE_EVTHR 宏來控制,在上面步驟5裏面,咱們將這個編譯選型設置爲ON,因此致使頭文件中由接口定義,可是卻沒有實現。
修改build/include目錄下的config文件中將 #define EVHTP_DISABLE_EVTHR代碼註釋掉,注意可能存在多行。從新編譯咱們的evhtp庫,會提示找不到pthread.h找不到,將VS中NuGet找到pthread的庫安裝便可。
若是提示timespec重定義錯誤,在預處理宏中加上 HAVE_STRUCT_TIMESPEC 定義
編譯成功運行工程,經過web頁面發送請求,成功。經過ProcessExplorer工具查看,程序也是有17個線程。遇到過沒編譯好,只有一個線程狀況。
附上我編譯後的源代碼地址:https://github.com/kswangxing/evhtp_win
裏面包含編譯後代碼。
編譯環境:VS2019 64位