C++ erreur: référence à la non-membre statique fonction doit être appelée
Je suis en train de créer une classe abstraite de base du comportement de libuv de fonctions de gestion de réseau.
#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 précédemment montré code, c'est que lorsque j'essaie de compiler, je reçois le message d'erreur suivant:
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 il points de listen_uv_listen_uv_connection_cb
comme le coupable.
Quelqu'un peut m'expliquer, pourquoi est-ce une erreur, et comment suis-je censé faire?
La uv_listen()
et uv_connection_cb
signatures 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);
supprimer les poignées de pointeur null par lui-même, votre chèque est redondant
Merci, ne savent pas à ce sujet.
Pouvez-vous montrer le réel
Bien sûr, l'ajouter à la question.
Merci, ne savent pas à ce sujet.
Pouvez-vous montrer le réel
uv_listen()
signature s'il vous plaît?Bien sûr, l'ajouter à la question.
OriginalL'auteur almosnow | 2014-11-12
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas convertir les non-statique de la fonction de membre d'un pointeur de fonction, même avec la même signature, techniquement fonction membre a un paramètre caché appelé
this
. L'une des solution est de fairelisten_uv_listen_uv_connection_cb
statique:PS pour être en mesure d'appeler un non-statique méthode que vous aurait besoin d'un moyen pour obtenir un pointeur vers votre
_tcp
exemple de "uv_stream_t* flux de paramètre". Je suggère d'utiliser "void* uv_handle_t.les données de" pointeur à partir de ce doc http://docs.libuv.org/en/latest/handle.html#c.uv_handle_tBien sûr, vous devez attribuer
this
pointeur versuv_handle_t.data
lors de l'initialisation deuv_tcp_t *
:et je voudrais déplacer ce code d'initialisation de constructeur.
Vous aurait besoin de tels statique wrapper pour chaque rappel que vous allez utiliser avec cette bibliothèque. Avec c++11, vous pouvez probablement utiliser lambda à la place.
listen_uv_listen_uv_connection_cb
fonction.Pour donner plus de détails,
uv_tcp_t* tcp
détient une référence à la réalité de la connexion tcp. Si je voulais faire quelque chose avec cette connexion danslisten_uv_listen_uv_connection_cb
(que j'ai certainement le faire) que j'ai faisuv_tcp_t* tcp
statique trop, et si je faistcp
statique alors je ne serais pas capable de bander de nouvelles connexions en faisant plus denew _tcp()
instances. Donc, c'est le problème.non, vous n'avez pas à faire
uv_tcp_t* tcp
statique, vous l'obtenir dans un premier paramètre dans la fonction de rappel. Voir mise à jour de réponseMerci @Slava, et merci pour la solution de contournement. J'ai dû accepter l'autre réponse, car elle m'a donné un aperçu sur pourquoi je ne peux pas utiliser un pointeur de fonction dans ce cas particulier, et de la sorte de se sentir mal parce que votre réponse est vraiment bon. Je vais faire usage de la propriété de données sur uv_tcp_t passer autour de mon instance de référence. Merci encore :D!
lorsque vous travaillez avec des C-API et de fournir un rappel vous toujours (si une bibliothèque bien conçu, bien sûr) à obtenir une
cookie
- généralement un vide pointeur vers les données de l'utilisateur, directement ou indirectement (comme dans ce cas), c'est la méthode courante d'utiliser de tels rappels en C++OriginalL'auteur Slava
La
uv_listen()
de retour d'appel connecteur attend unstatic
ou libre (en dehors de la classe) de la fonction.Ainsi, vous devez déclarer votre fonction comme ceci
Bien, le
static_cast<>
en a réellement besoin de votre_tcp
classe hérite deuv_stream_t
Étendre sur votre commentaire
Il y a une différence entre membre de la classe des pointeurs de fonction, qui ont besoin d'être lié à une instance de classe pour l'appel, et la plaine des pointeurs de fonction, qui fonctionne pour n'importe quelle définition de la fonction.
Pourquoi
uv_listen()
s'attend à un simple pointeur de fonction, c'est difficile à dire. Peut-être parce que c'est un natif C-API (en fait, je ne sais pas), ou pour des raisons de flexibilité.REMARQUE: Vous ne devriez pas utiliser des caractères de soulignement pour les symboles (comme dans
class _tcp
)!OriginalL'auteur πάντα ῥεῖ
Il devrait y avoir pas de point-virgule à la fin de la définition de la fonction.
Et vous devriez écrire constructeur/copie ctr/affectation opérateur pour cette classe.
Merci pour votre observation @ravi, le code ne fonctionne toujours pas.
OriginalL'auteur ravi