【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:(附件)

相关文章
相关标签/搜索