我正在尝试创建一个类来抽象libuv网络功能的一些基本行为。
#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);
}
};
先前显示的代码的问题在于,当我尝试对其进行编译时,出现以下错误:
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);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
它指向listen_uv_listen_uv_connection_cb
罪魁祸首。
有人可以向我解释,为什么是错误,我应该如何解决?
在uv_listen()
和uv_connection_cb
签名的声明如下
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);
您不能将非静态成员函数转换为具有相同签名的函数指针,因为从技术上讲,成员函数具有名为的隐藏参数this
。解决方案之一是使listen_uv_listen_uv_connection_cb
静态:
class _tcp {
uv_tcp_t* tcp = NULL;
public:
~_tcp() { delete tcp; }
static 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,
&_tcp::listen_uv_listen_uv_connection_cb);
}
};
PS能够调用非静态方法,您将需要一种方法来_tcp
从“ uv_stream_t * stream”参数获取指向您实例的指针。我建议使用此文档http://docs.libuv.org/en/latest/handle.html#c.uv_handle_t的“ void * uv_handle_t.data”指针
static void listen_uv_listen_uv_connection_cb(uv_stream_t* stream, int status) {
_tcp *tcp = static_cast<_tcp *>( stream->data );
tcp->regularMethod();
}
当然,您应该在初始化时分配this
指向的指针:uv_handle_t.data
uv_tcp_t *
void listen(const char* host, int port) {
tcp = new uv_tcp_t();
uv_tcp_init(uv_default_loop(), tcp);
tcp->data = this; // do not forget it
...
}
然后将初始化代码移至构造函数。
对于要与此库一起使用的每个回调,您都需要这样的静态包装器。在c ++ 11中,您可能可以改用lambda。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句