開源庫evhtp在windows下編譯

工做須要搭建基於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 }
View Code

編譯後,運行程序。提示 沒法定位程序點輸入點 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位

相關文章
相關標籤/搜索