作者:阿凡卢

出处:http://www.cnblogs.com/luxiaoxun/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

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

windows下编译及使用libevent

Libevent官网:http://libevent.org/

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

比较不错的参考:http://download.csdn.net/detail/sparkliang/2001038

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的解决方法:

1、将过去的工程用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:(附件)