ARM平台移植libevent-2.0.22-stable

时间:2021-07-18 00:16:41
系统环境:Ubuntu 14.04.3 LTS
源码:libevent-2.0.22-stable.tar.gz
交叉编译环境:arm-none-linux-gnueabi-


[zhaojq@virtual-machine]# tar -zxvf libevent-2.0.22-stable.tar.gz
[zhaojq@virtual-machine]# cd libevent-2.0.22-stable/
[zhaojq@virtual-machine]# ./configure --prefix=/home/kt/libevent --host=arm-none-linux CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++

[zhaojq@virtual-machine]# make
[zhaojq@virtual-machine]# make install
生成成功
交叉编译后的文件在/home/zhaojq/libevent目录下
[zhaojq@virtual-machine libevent]# ls
bin  include  lib

libevent头文件在include目录
[zhaojq@virtual-machine libevent/include]# ls
evdns.h  event2  event.h  evhttp.h  evrpc.h  evutil.h

交叉编译后的动态库文件在lib目录
[zhaojq@virtual-machine libevent/lib]# ls
libevent-2.0.so.5           libevent_extra-2.0.so.5.1.9    libevent_openssl.so
libevent-2.0.so.5.1.9       libevent_extra.a               libevent_pthreads-2.0.so.5
libevent.a                  libevent_extra.la              libevent_pthreads-2.0.so.5.1.9
libevent_core-2.0.so.5      libevent_extra.so              libevent_pthreads.a
libevent_core-2.0.so.5.1.9  libevent.la                    libevent_pthreads.la
libevent_core.a             libevent_openssl-2.0.so.5      libevent_pthreads.so
libevent_core.la            libevent_openssl-2.0.so.5.1.9  libevent.so
libevent_core.so            libevent_openssl.a             pkgconfig
libevent_extra-2.0.so.5     libevent_openssl.la


编译test实例
[zhaojq@virtual-machine]# vim libevent_test.cpp
#include <errno.h>  
#include <stdlib.h>
#include <string.h>

#include <event2/event.h>
#include <event2/buffer.h>
#include <event2/http.h>
#include <event2/http_struct.h>
#include <event2/keyvalq_struct.h>

// (default)
#define HTTP_CONTENT_TYPE_URL_ENCODED "application/json;charset=UTF-8"
// (use for files: picture, mp3, tar-file etc.)
#define HTTP_CONTENT_TYPE_FORM_DATA "multipart/form-data"
// (use for plain text)
#define HTTP_CONTENT_TYPE_TEXT_PLAIN "text/plain"

#define REQUEST_POST_FLAG 2
#define REQUEST_GET_FLAG 3

struct http_request_method {
struct evhttp_uri *uri;
struct event_base *base;
struct evhttp_connection *cn;
struct evhttp_request *req;
};

struct http_request_get:public http_request_method{
};

struct http_request_post:public http_request_method{
char *token;
char *content_type;
char *post_data;
};

/************************** Ahead Declare ******************************/
void http_requset_post_cb(struct evhttp_request *req, struct http_request_post *http_req_post);
//void http_requset_get_cb(struct evhttp_request *req, void *arg);
int start_url_request_get(struct http_request_get *http_req_get);
int start_url_request_post(struct http_request_post *http_req_post);

/************************** Tools Function ******************************/
static inline void print_request_head_info(struct evkeyvalq *header)
{
struct evkeyval *first_node = header->tqh_first;
while (first_node) {
printf("key:%s value:%s\n", first_node->key, first_node->value);
first_node = first_node->next.tqe_next;
}
}

/************************************************************
Function: print_uri_parts_info
Author: Zhaojq
Version: 2.0
Date: 2016/05/17
Description: 打印URI参数

Called By: http_request_new

History:
<author><time><version ><desc>
Zhaojq16/05/172.0build this moudle
***********************************************************/
static inline void print_uri_parts_info(const struct evhttp_uri * http_uri)
{
printf("scheme:%s ", evhttp_uri_get_scheme(http_uri));
printf("host:%s ", evhttp_uri_get_host(http_uri));
printf("path:%s\n", evhttp_uri_get_path(http_uri));
//printf("port:%d ", evhttp_uri_get_port(http_uri));
//printf("query:%s ", evhttp_uri_get_query(http_uri));
//printf("userinfo:%s ", evhttp_uri_get_userinfo(http_uri));
//printf("fragment:%s\n", evhttp_uri_get_fragment(http_uri));
}

/************************************************************
Function: http_requset_post_cb
Author: Zhaojq
Version: 2.0
Date: 2016/05/17
Description: HTTP POST 协议响应包

Called By: start_url_request_post

History:
<author><time><version ><desc>
Zhaojq16/05/172.0build this moudle
***********************************************************/
void http_requset_post_cb(struct evhttp_request *req, void *arg)
{
struct http_request_post *http_req_post = (struct http_request_post *)arg;
switch(req->response_code)
{
//request completed ok 200
case HTTP_OK:
{
//returns the input buffer(输入缓冲区)
struct evbuffer* buf = evhttp_request_get_input_buffer(req);
size_t len = evbuffer_get_length(buf);
print_request_head_info(req->output_headers);

printf("len:%zu body size:%zu\n", len, req->body_size);
char *tmp = (char *)malloc(len+1);
//Makes the data at the beginning of an evbuffer contiguous.
memcpy(tmp, evbuffer_pullup(buf, -1), len);
tmp[len] = '\0';
printf("HTML BODY:%s\n", tmp);
free(tmp);

//Exit the event loop after the specified time
event_base_loopexit(http_req_post->base, 0);
break;
}
//the uri moved permanently 301
case HTTP_MOVEPERM:
printf("the uri moved permanently\n");
break;

//the uri moved temporarily 302
case HTTP_MOVETEMP:
{
const char *new_location = evhttp_find_header(req->input_headers, "Location");
struct evhttp_uri *new_uri = evhttp_uri_parse(new_location);
evhttp_uri_free(http_req_post->uri);
http_req_post->uri = new_uri;
start_url_request_post(http_req_post);
return;
}

default:
event_base_loopexit(http_req_post->base, 0);
return;
}
}

/************************************************************
Function: start_url_request_post
Author: Zhaojq
Version: 2.0
Date: 2016/05/17
Description: 封装HTTP POST 协议请求包

Called By: start_http_requset

History:
<author><time><version><desc>
Zhaojq16/05/172.0build this moudle
***********************************************************/
int start_url_request_post(struct http_request_post *http_req_post)
{
if(http_req_post->cn) {
//free an http connection
evhttp_connection_free(http_req_post->cn);
}

//return -1 if there is no port set.
int port = evhttp_uri_get_port(http_req_post->uri);
//return an evhttp_connection object that can be used for making requests
http_req_post->cn = evhttp_connection_base_new(http_req_post->base, NULL, evhttp_uri_get_host(http_req_post->uri), (port == -1 ? 80 : port));

//creates a new request object that needs to be filled in with the request parameters. The callback is executed when the request completed or an error occurred.
http_req_post->req = evhttp_request_new(http_requset_post_cb, http_req_post);

const char *path = evhttp_uri_get_path(http_req_post->uri);
//make an HTTP request over the specified connection.
evhttp_make_request(http_req_post->cn, http_req_post->req, EVHTTP_REQ_POST, path ? path : "/");
//append data to the end of an evbuffer
evbuffer_add(http_req_post->req->output_buffer, http_req_post->post_data, strlen(http_req_post->post_data));
//adds a header to a list of existing headers.
evhttp_add_header(http_req_post->req->output_headers, "Content-Type", http_req_post->content_type);
evhttp_add_header(http_req_post->req->output_headers, "Host", evhttp_uri_get_host(http_req_post->uri));
return 0;
}

/************************************************************
Function: http_request_new
Author: Zhaojq
Version: 2.0
Date: 2016/05/17
Description: 初始化HTTP POST/GET 协议请求包

Called By: start_http_requset

History:
<author><time><version ><desc>
Zhaojq16/05/172.0build this moudle
***********************************************************/
void *http_request_new(struct event_base* base, const char *url, int req_meth_flag, \
const char *token, const char *content_type, const char* data)
{
int len = 0;
//初始化HTTP GET 协议请求包
if (req_meth_flag == REQUEST_GET_FLAG) {
len = sizeof(struct http_request_get);
struct http_request_get *http_req_get = (struct http_request_get *)calloc(1, len);
//helper function to parse a URI-Reference as specified by RFC3986.
http_req_get->uri = evhttp_uri_parse(url);
print_uri_parts_info(http_req_get->uri);
http_req_get->base = base;
return http_req_get;
}
//初始化HTTP POST 协议请求包
else if(req_meth_flag == REQUEST_POST_FLAG) {
len = sizeof(struct http_request_post);
struct http_request_post *http_req_post = (struct http_request_post *)calloc(1, len);
http_req_post->uri = evhttp_uri_parse(url);
print_uri_parts_info(http_req_post->uri);
http_req_post->base = base;
if (content_type == NULL) {
content_type = HTTP_CONTENT_TYPE_URL_ENCODED;
}
http_req_post->token = strdup(token);
http_req_post->content_type = strdup(content_type);

if (data == NULL) {
http_req_post->post_data = NULL;
} else {
http_req_post->post_data = strdup(data);
}
return http_req_post;
}
return NULL;
}

/************************************************************
Function: http_request_free
Author: Zhaojq
Version: 2.0
Date: 2016/05/17
Description: 初始化HTTP POST/GET 协议请求包

Called By: main

History:
<author><time><version ><desc>
Zhaojq16/05/172.0build this moudle
***********************************************************/
void http_request_free(struct http_request_get *http_req_get, int req_meth_flag)
{
evhttp_connection_free(http_req_get->cn);
//Free all memory allocated for a parsed uri. Only use this for URIs generated by evhttp_uri_parse.
evhttp_uri_free(http_req_get->uri);
if (req_meth_flag == REQUEST_GET_FLAG) {
free(http_req_get);
} else if(req_meth_flag == REQUEST_POST_FLAG) {
struct http_request_post *http_req_post = (struct http_request_post*)http_req_get;
if (http_req_post->content_type) {
free(http_req_post->content_type);
}
if (http_req_post->post_data) {
free(http_req_post->post_data);
}
free(http_req_post);
}
http_req_get = NULL;
}

/************************************************************
Function: start_http_requset
Author: Zhaojq
Version: 2.0
Date: 2016/05/17
Description: 创建HTTP POST/GET 协议请求包

Calls: http_request_new, start_url_request
Called By: main

History:
<author><time><version ><desc>
Zhaojq16/05/172.0build this moudle
***********************************************************/
void *start_http_requset(struct event_base* base, const char *url, int req_meth_flag, \
const char *token, const char *content_type, const char* data)
{
printf("data = %s\n",data);
if (req_meth_flag == REQUEST_GET_FLAG) {
struct http_request_get *http_req_get = (struct http_request_get *)http_request_new(base, url, req_meth_flag, token, content_type, data);
start_url_request_get(http_req_get);
return http_req_get;
} else if(req_meth_flag == REQUEST_POST_FLAG) {
struct http_request_post *http_req_post = (struct http_request_post *)http_request_new(base, url, req_meth_flag, token, content_type, data);
start_url_request_post(http_req_post);
return http_req_post;
}
return NULL;
}

int main(int argc, char *argv[])
{
struct event_base* base = event_base_new();//分配并且返回一个新的具有默认设置的event_base

struct http_request_post *http_req_post = (struct http_request_post *)start_http_requset(base,
"http://www.url.com",
REQUEST_POST_FLAG,
HTTP_CONTENT_TYPE_URL_ENCODED,
"Postdata");
/*
struct http_request_get *http_req_get = start_http_requset(base,
"http://127.0.0.1?name=winlin",
REQUEST_GET_FLAG,
NULL, NULL);
*/
//Event dispatching loop
event_base_dispatch(base);
http_request_free((struct http_request_get *)http_req_post, REQUEST_POST_FLAG);
//http_request_free(http_req_get, REQUEST_GET_FLAG);
event_base_free(base);
return 0;
}
[zhaojq@virtual-machine]# arm-none-linux-gnueabi-g++ -levent -I/home/kt/libevent/include -L/home/kt/libevent/lib -o libevent_test libevent.cpp
编译通过,在当前目录生成libevent_test可执行文件

将/home/zhaojq/libevent目录下的所有文件和pkgconfig目录都拷贝到ARM设备上文件系统的/lib目录,
libevent_test拷贝到ARM设备上

执行./libevent_test,移植成功。