I'm trying to create a class to abstract some basic behavior of libuv's networking functions.
#define TCP_BACKLOG 256
class _tcp {
uv_tcp_t* tcp = NULL;
public:
~_tcp() { delete tcp; }
void listen_uv_listen_uv_connection_cb(uv_stream_t* stream, int status) {
printf("NEW CONNECTION\n");
}
void listen(const char* host, int port) {
tcp = new uv_tcp_t();
uv_tcp_init(uv_default_loop(), tcp);
sockaddr_in* addr = new sockaddr_in();
uv_ip4_addr(host, port, addr);
uv_tcp_bind(tcp, (const sockaddr*)addr, 0);
delete addr;
uv_listen((uv_stream_t*)tcp, TCP_BACKLOG, listen_uv_listen_uv_connection_cb);
}
};
The problem with the previously shown code is that when I try to compile it I get the following error:
error: reference to non-static member function must be called
on: uv_listen((uv_stream_t*)tcp, TCP_BACKLOG, listen_uv_listen_uv_connection_cb);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
And it points to listen_uv_listen_uv_connection_cb
as the culprit.
Can someone explain to me, why is that an error, and how am I supposed to fix it?
The uv_listen()
and uv_connection_cb
signatures are declared as follows
UV_EXTERN int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb);
typedef void (*uv_connection_cb)(uv_stream_t* server, int status);
You cannot convert non-static member function to a pointer to function even with the same signature, as technically member function has a hidden parameter called
this
. One of the solution is to makelisten_uv_listen_uv_connection_cb
static:PS to be able to call a non-static method you would need a way to get a pointer to your
_tcp
instance from "uv_stream_t* stream" parameter. I would suggest to use "void* uv_handle_t.data" pointer from this doc http://docs.libuv.org/en/latest/handle.html#c.uv_handle_tOf course you should assign
this
pointer touv_handle_t.data
when you initializeuv_tcp_t *
:and I would move this initialization code to constructor.
You would need such static wrapper for every callback you are going to use with this library. With c++11 you probably can use lambda instead.