Alex Barry Alex Barry - 3 months ago 11
C++ Question

'Forward Declaration of Struct' while retrieving libevent connection Information

I am trying to retrieve original connection information requested within a callback registered with libevent:

#include <evhttp.h>
#include <iostream>

//Process a request
void process_request(struct evhttp_request *req, void *arg){

//Get the request type (functions correctly)
std::cout << req->type << std::endl;

//Get the address and port requested that triggered the callback
//When this is uncommented, the code no longer compiles and throws
//the warning below
struct evhttp_connection *con = req->evcon;
std::cout << con->address << con->port << std::endl;
}

int main () {

//Set up the server
struct event_base *base = NULL;
struct evhttp *httpd = NULL;
base = event_init();
if (base == NULL) return -1;
httpd = evhttp_new(base);
if (httpd == NULL) return -1;

//Bind the callback
if (evhttp_bind_socket(httpd, "0.0.0.0", 12345) != 0) return -1;
evhttp_set_gencb(httpd, process_request, NULL);

//Start listening
event_base_dispatch(base);
return 0;
}


However, I am receiving the following error:

$g++ -o basic_requests_server basic_requests_server.cpp -lpthread -levent -std=c++11

basic_requests_server.cpp:45:18: error: invalid use of incomplete type ‘struct evhttp_connection’
std::cout << con->address << con->port << std::endl;
^
In file included from /usr/include/evhttp.h:41:0,
from basic_requests_server.cpp:1:
/usr/include/event2/http.h:427:8: error: forward declaration of ‘struct evhttp_connection’
struct evhttp_connection *evhttp_connection_base_new(


Why can't I access the elements of this struct?

Answer

Why can't I access the elements of this struct?

As far as I understand, connections (that is struct evhttp_connection) are meant for internal purposes only.
You should not directly use them or their fields, but you can get a pointer to a connection and pass that pointer around.
It had been done on purpose, to avoid clients bind to the internal representation of a connection (that can change silently this way thus).
That's why the type is not actually exposed. You can think of it as an opaque pointer you are not allowed to dereference.

See here for an in-depth explanation.