À l'aide d'un membre de classe C++ fonctionner comme un C fonction de rappel
J'ai une bibliothèque C qui a besoin d'une fonction de rappel d'être enregistré pour personnaliser le traitement. Le Type de la fonction de rappel est int a(int *, int *)
.
Je suis en train d'écrire du code C++ semblable à la suivante et tentez d'enregistrer une classe C++ la fonction comme la fonction de rappel:
class A {
public:
A();
~A();
int e(int *k, int *j);
};
A::A()
{
register_with_library(e)
}
int
A::e(int *k, int *e)
{
return 0;
}
A::~A()
{
}
Le compilateur renvoie l'erreur suivante:
In constructor 'A::A()',
error:
argument of type ‘int (A::)(int*, int*)’ does not match ‘int (*)(int*, int*)’.
Mes questions:
- Tout d'abord est-il possible de s'inscrire à une classe C++ memeber fonction comme je suis en train de faire et si oui, comment?
(J'ai lu de 32,8 à http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html. Mais à mon avis il ne résout pas le problème) - Est-il un autre/de meilleure façon de remédier à cette situation?
Vous devez vous connecter pour publier un commentaire.
Vous pouvez le faire que si la fonction membre statique.
Non-fonctions membres statiques de la classe A ont implicite premier paramètre de type
class A*
qui correspond à ce pointeur. C'est pourquoi vous pourriez vous inscrire uniquement si la signature de la fonction de rappel a également eu le premier paramètre declass A*
type.Vous pouvez également le faire si la fonction de membre n'est pas statique, mais elle exige un peu plus de travail (voir aussi Convertir pointeur de fonction C++ à c de pointeur de fonction):
Cet exemple est complet dans le sens qu'il compile:
Vous aurez besoin de la
c++11
drapeau. Dans le code que vous voyez queregister_with_library(func)
est appelé, oùfunc
est une fonction statique dynamiquement lié à la fonction de membre dee
.return func(args...);
au lieu defunc(args...);
de la ligne 11Le problème est que la méthode != fonction. Le compilateur va transformer votre méthode pour quelque chose comme ça:
Donc, c'est sûr que vous ne pouvez pas passer, parce que l'instance de classe ne peut pas être passé en argument. Une façon de contourner ce problème consiste à faire de la méthode statique, de cette manière, il aurait le bon type. Mais il ne sera pas toute instance de classe, et l'accès à la non-statique des membres de la classe.
L'autre solution est de déclarer une fonction avec un Pointeur statique à une initialisation la première fois. La fonction de redirection de l'appel à la classe :
Alors vous pouvez vous inscrire à la fonction de rappel.
a->(j, k);
, avez-vous manqué de taper lee
?Bien ...si vous êtes sur une plate-forme win32, il est toujours le méchant Médiateur de la sorte ...
Médiateur dans Win32: la Simplification des rappels à la non-fonctions membres statiques
C'est une solution mais je ne recommande pas de l'utiliser.
Il a une bonne explication, et il est bon de savoir qu'il existe.
Le problème avec l'aide d'une fonction membre, c'est qu'il a besoin d'un objet sur lequel l'action et C ne sait pas sur les objets.
Le plus simple serait de faire ce qui suit:
e
fonction ne nécessite pas d'accèsthis
.Dans cette solution, nous avons une classe de modèle
avec la méthode statique pour le "c" fonction de rappel.
Cette classe contient un "ordinaire" de l'objet ( avec une fonction membre nommée " callback() qui sera finalement appelé).
Une fois votre classe (ici, Un) est définie, elle peut être facilement utilisée:
Exemple complet: