【libevent】windows下編譯及使用

做者:阿凡盧html

出處:http://www.cnblogs.com/luxiaoxun/windows

本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。安全

vs命令行工具使用:http://tieba.baidu.com/p/3335013298網絡

windows下編譯及使用libevent多線程

Libevent官網:http://libevent.org/app

libevent API:http://www.monkey.org/~provos/libevent/doxygen-2.0.1/index.htmlsocket

比較不錯的參考:http://download.csdn.net/detail/sparkliang/2001038ide

windows 7下編譯:函數

編譯環境: windows 7 + VS2010工具

(1)解壓libevent到F:\libevent\libevent-2.0.21-stable

(2)打開Microsoft visual studio 2010命令行工具

(3)修改如下三個文件,添加宏定義:

在如下3個文件開頭添加「#define _WIN32_WINNT 0x0500」

libevent-2.0.21-stable\event_iocp.c

libevent-2.0.21-stable\evthread_win32.c

libevent-2.0.21-stable\listener.c

(4)使用VS命令提示工具編譯:

cd/d F:\libevent\libevent-2.0.21-stable

nmake /f Makefile.nmake

(5)編譯結果:

libevent_core.lib:All core event and buffer functionality. This library contains all the event_base, evbuffer, bufferevent, and utility functions.

libevent_extras.lib:This library defines protocol-specific functionality that you may or may not want for your application, including HTTP, DNS, and RPC.

libevent.lib:This library exists for historical reasons; it contains the contents of both libevent_core and libevent_extra. You shouldn’t use it; it may go away in a future version of Libevent.

(6)VS2010下使用lib

新建一個VC++控制檯項目:

環境配置:

項目下建一個Lib目錄,將上面三個lib文件copy到該目錄下。

新建一個Include目錄,將F:\libevent\libevent-2.0.21-stable\include下的文件和文件夾copy到該目錄下,F:\libevent\libevent-2.0.21-stable\WIN32-Code下的文件copy到該目錄下,2個event2目錄下的文件可合併一塊兒。

main代碼:

複製代碼

// LibeventTest.cpp : 定義控制檯應用程序的入口點。//#include "stdafx.h"#include <string.h>#include <errno.h>#include <stdio.h>#include <signal.h>#ifndef WIN32 #include <netinet/in.h># ifdef _XOPEN_SOURCE_EXTENDED #  include <arpa/inet.h># endif #include <sys/socket.h>#endif#include "event2/bufferevent.h"#include "event2/buffer.h"#include "event2/listener.h"#include "event2/util.h"#include "event2/event.h"#include <WinSock2.h>static const char MESSAGE[] = "Hello, World!\n";static const int PORT = 9995;static void conn_writecb(struct bufferevent *bev, void *user_data) {    struct evbuffer *output = bufferevent_get_output(bev);    if (evbuffer_get_length(output) == 0)    {        printf("flushed answer\n");        bufferevent_free(bev);    } }static void conn_eventcb(struct bufferevent *bev, short events, void *user_data) {    if (events & BEV_EVENT_EOF)    {        printf("Connection closed.\n");    }    else if (events & BEV_EVENT_ERROR)    {        printf("Got an error on the connection: %s\n",            strerror(errno));/*XXX win32*/    }    /* None of the other events can happen here, since we haven't enabled     * timeouts */    bufferevent_free(bev); }static void signal_cb(evutil_socket_t sig, short events, void *user_data) {    struct event_base *base = (struct event_base *)user_data;    struct timeval delay = { 2, 0 };    printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");    event_base_loopexit(base, &delay); }static void listener_cb(struct evconnlistener *listener, evutil_socket_t fd,    struct sockaddr *sa, int socklen, void *user_data) {    struct event_base *base = (struct event_base *)user_data;    struct bufferevent *bev;    bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);    if (!bev)    {        fprintf(stderr, "Error constructing bufferevent!");        event_base_loopbreak(base);        return;    }    bufferevent_setcb(bev, NULL, conn_writecb, conn_eventcb, NULL);    bufferevent_enable(bev, EV_WRITE);    bufferevent_disable(bev, EV_READ);    bufferevent_write(bev, MESSAGE, strlen(MESSAGE)); }int main(int argc, char **argv) {    struct event_base *base;    struct evconnlistener *listener;    struct event *signal_event;    struct sockaddr_in sin; #ifdef WIN32    WSADATA wsa_data;    WSAStartup(0x0201, &wsa_data);#endif

    base = event_base_new();    if (!base)    {        fprintf(stderr, "Could not initialize libevent!\n");        return 1;    }    memset(&sin, 0, sizeof(sin));    sin.sin_family = AF_INET;    sin.sin_port = htons(PORT);    listener = evconnlistener_new_bind(base, listener_cb, (void *)base,        LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1,        (struct sockaddr*)&sin,        sizeof(sin));    if (!listener)    {        fprintf(stderr, "Could not create a listener!\n");        return 1;    }    signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);    if (!signal_event || event_add(signal_event, NULL)<0)    {        fprintf(stderr, "Could not create/add a signal event!\n");        return 1;    }    event_base_dispatch(base);    evconnlistener_free(listener);    event_free(signal_event);    event_base_free(base);    printf("done\n");    return 0; }

複製代碼

項目屬性設置:

VC++目錄:

包含目錄,添加:F:\Projects\LibeventTest\LibeventTest\Include;

庫目錄,添加:F:\Projects\LibeventTest\LibeventTest\Lib;

C/C++:

代碼生成-->運行庫:多線程調試 (/MTd)(Debug下),多線程 (/MT)(Release下)

鏈接器:

輸入:ws2_32.lib;wsock32.lib;libevent.lib;libevent_core.lib;libevent_extras.lib;

ws2_32.lib;wsock32.lib;是用來編譯Windows網絡相關的程序庫。

編譯,生成!

編譯好的libevent lib下載 Libevent2.0.21.rar

 

初次使用vs2013因爲安全機制引起error的解決方法:

一、將過去的工程用VS2010打開的時候。你有可能會遇到一大堆的警告:warning C4996。 

好比:warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. 
緣由是Visual C++ 2005使用了更加安全的run-time library routines。 
新的Security CRT functions(就是那些帶有「_s」後綴的函數): 
http://msdn2.microsoft.com/en-us/library/wd3wzwts(VS.80).aspx 
那麼如何搞定這些警告呢:

緣由解釋
這種微軟的警告,主要由於那些C庫的函數,不少函數內部是不進行參數檢測的(包括越界類的),微軟擔憂使用這些會形成內存異常,因此就改寫了一樣功能的函數,改寫了的函數進行了參數的檢測,使用這些新的函數會更安全和便捷。關於這些改寫的函數你不用專門去記憶,由於編譯器對於每一個函數在給出警告時,都會告訴你相應的安全函數,查看警告信息就能夠獲知,在使用時也再查看一下MSDN詳細瞭解。庫函數改寫例子:
mkdir改寫爲 _mkdir 
fopen」改寫爲 fopen_s 
stricmp改寫爲 stricmp_s
sprintf改寫爲sprintf_s

strcpy改寫爲strcpy_s

    解決方案:
1> 根據下面的warning提示:參見「fopen」的聲明
        消息:「This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.」
        因此能夠將函數按warning提示的第二句,改成使用fopen_s函數便可:
        例如:FILE *pFile=fopen("1.txt", "w");
           改成:
           FILE* pFile;
           fopen_s(&pFile, "1.txt", "w"); 
2> 仍是根據warning提示的地三句話:use _CRT_SECURE_NO_DEPRECATE
        項目|屬性|配置屬性|C/C++|命令行|附加選項,加入【/D "_CRT_SECURE_NO_DEPRECATE" 】(注:加入中括號中完整的內容)
3> 下降警告級別:項目|屬性|配置屬性|C/C++|常規,本身根據狀況下降警告級別(此法不推薦)
    注意:高度重視警告:使用編譯器的最高警告級別。應該要求構建是乾淨利落的(沒有警告)。理解全部警告。經過 修改代碼而不是下降警告級別來排除警告。

方法一:手工將原來的舊函數替換成新的Security CRT functions。 
方法二:屏蔽這個警告。 
            在預編譯頭文件stdafx.h裏(注意:必定要在沒有include任何頭文件以前)定義下面的宏: 
            #define _CRT_SECURE_NO_DEPRECATE 
            或者#param warning(disable:4996) 
方法二沒有使用新的更安全的CRT函數,顯然不是一個值得推薦的方法,但是你又不想一個一個地改。 
那麼還有一個更方便的方法: 
在預編譯頭文件stdafx.h裏(一樣要在沒有include任何頭文件以前)定義下面的宏: 
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 
在連接的時候便會自動將舊函數替換成Security CRT functions。 
注意:這個方法雖然使用了新的函數,可是不能消除警告你還得同時使用方法二。。。

 

補充缺失的event-config.h:(附件)

相關文章
相關標籤/搜索