我正在尝试创建一个类来抽象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);
发布于 2014-11-13 02:52:45
即使具有相同的签名,也不能将非静态成员函数转换为指向函数的指针,因为从技术上讲,成员函数有一个名为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);
}
};
为了能够调用非静态方法,您需要一种从"uv_stream_t* _tcp
“参数获取指向流实例的指针的方法。我建议使用此文档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();
}
当然,您应该在初始化uv_tcp_t *
时将this
指针赋值给uv_handle_t.data
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。
发布于 2014-11-13 02:37:48
void listen_uv_listen_uv_connection_cb(uv_stream_t* stream, int status) {
printf("NEW CONNECTION\n");
}; <<<<<remove ;
函数定义的末尾不能有分号。
你应该为这个类编写构造函数/复制ctr/赋值运算符。
https://stackoverflow.com/questions/26894063
复制相似问题