J'essaie de créer une classe pour résumer certains comportements de base des fonctions de réseau de 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);
}
};
Le problème avec le code précédemment affiché est que lorsque j'essaie de le compiler, j'obtiens l'erreur suivante:
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);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Et cela désigne listen_uv_listen_uv_connection_cb
comme le coupable.
Quelqu'un peut-il m'expliquer pourquoi est-ce une erreur et comment suis-je censé y remédier?
Les signatures uv_listen()
et uv_connection_cb
sont déclarées comme suit
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);
Vous ne pouvez pas convertir une fonction membre non statique en un pointeur pour fonctionner même avec la même signature, car techniquement la fonction membre a un paramètre masqué appelé this
. Une des solutions est de rendre listen_uv_listen_uv_connection_cb
statique:
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 pour pouvoir appeler une méthode non statique, vous auriez besoin d'un moyen d'obtenir un pointeur vers votre _tcp
instance à partir du paramètre "uv_stream_t * stream". Je suggérerais d'utiliser le pointeur "void * uv_handle_t.data" de ce document http://docs.libuv.org/en/latest/handle.html#c.uv_handle_t
static void listen_uv_listen_uv_connection_cb(uv_stream_t* stream, int status) {
_tcp *tcp = static_cast<_tcp *>( stream->data );
tcp->regularMethod();
}
Bien sûr, vous devez attribuer un this
pointeur à uv_handle_t.data
lorsque vous initialisez 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
...
}
et je déplacerais ce code d'initialisation vers le constructeur.
Vous auriez besoin d'un tel wrapper statique pour chaque rappel que vous allez utiliser avec cette bibliothèque. Avec c ++ 11, vous pouvez probablement utiliser lambda à la place.
Cet article est collecté sur Internet, veuillez indiquer la source lors de la réimpression.
En cas d'infraction, veuillez [email protected] Supprimer.
laisse moi dire quelques mots