Pointeurs de fonction et des rappels de service en C
J'ai commencé à réviser les rappels. J'ai trouvé ce lien sur DONC:
Qu'est ce qu'un "rappel" en C et comment sont-ils mis en œuvre? Il a un bon exemple de callback qui est très similaire à ce que nous utilisons au travail. Cependant, j'ai essayé de le faire fonctionner, mais j'ai de nombreuses erreurs.
#include <stdio.h>
/* Is the actual function pointer? */
typedef void (*event_cb_t)(const struct event *evt, void *user_data);
struct event_cb
{
event_cb_t cb;
void *data;
};
int event_cb_register(event_ct_t cb, void *user_data);
static void my_event_cb(const struct event *evt, void *data)
{
/* do some stuff */
}
int main(void)
{
event_cb_register(my_event_cb, &my_custom_data);
struct event_cb *callback;
callback->cb(event, callback->data);
return 0;
}
Je sais que les rappels d'utiliser des pointeurs de fonction pour stocker une adresse d'une fonction. Mais il y a quelques choses que je trouve que je ne comprends pas:
- Ce que l'on entend par "enregistrement de la fonction de rappel" et "event dispatcher"?
Pourquoi ne pas inclure vos erreurs?
OriginalL'auteur ant2009 | 2009-03-10
Vous devez vous connecter pour publier un commentaire.
Ce code compile et s'exécute sous GCC-Wall.
Vous avez probablement besoin d'examiner si la fonction de rappel a l'ensemble struct event_cb ou pas - d'habitude, tu venais juste de transmettre les données parce que, comme l'a démontré, sinon, vous avez deux sources de ces informations (et une copie de rechange de le pointeur vers la fonction que vous êtes). Il y a beaucoup de nettoyage qui peut être fait sur ce point - mais il fonctionne.
Une question dans les commentaires, il demande: Est-ce un bon exemple d'un rappel?
Succinctement, pas - mais en partie parce qu'il n'y a pas d'infrastructures suffisantes ici.
Dans un sens, vous pouvez penser à la fonction de comparaison transmis à la
qsort()
oubsearch()
fonctions de rappel. Il est un pointeur vers une fonction qui est passée dans la fonction générique qui fait ce que la fonction générique ne peut faire pour lui-même.Un autre exemple d'une fonction de rappel est un signal fonction de gestionnaire. Vous dites que le système d'appel de votre fonction lors de l'événement - un signal se produit. Vous avez mis en place les mécanismes à l'avance de sorte que lorsque le système a besoin pour appeler une fonction, il sait quelle fonction appeler.
Le code de l'exemple est de tenter de fournir une description plus détaillée du mécanisme - un rappel avec un contexte. En C++, ce serait peut-être un foncteur.
Une partie du code que je travaille avec a très pointilleux exigences à propos de la gestion de la mémoire - lorsqu'il est utilisé dans un contexte particulier. Donc, pour les tests, j'utilise
malloc()
et al, mais dans la production, je dois mettre les allocateurs de mémoire à l'spécialisés allocateurs. Puis-je faire un appel de fonction dans l'emballage pour que les grincheux code pouvez remplacer la mémoire par défaut allocateurs avec ses propres versions de substitution et les substituts de travail OK, le code va se comporter comme avant. Ceux-ci sont une forme de rappel à nouveau, une forme qui n'a pas besoin de grand chose (ou rien) dans la voie de l'utilisateur des données de contexte.Systèmes de fenêtrage ont gestionnaires d'événements (rappels) qui sont enregistrés et que le GUI boucle principale sera d'appel lorsque des événements se produisent. Ceux habituellement besoin de contexte de l'utilisateur ainsi que le cas spécifique de l'information fournie par l'interface graphique du système.
Bonjour, Merci pour votre effort. Je suis juste d'entrer dans des pointeurs de fonction, comme je vais l'utiliser au travail pour la première fois. Est-ce un bon exemple d'un rappel. L'exemple que je vous ai donné semble proche de ce que nous utilisons. Si vous savez quelque chose de mieux?
Pas clair. Qui est "sauvé" ? où est-il défini dans votre code?
La variable
saved
est défini dans le code:static struct event_cb saved = { 0, 0 };
OriginalL'auteur Jonathan Leffler
"enregistrement de la fonction de rappel" est le fait de dire à la underyling système qui précise la fonction à appeler, et (en option) avec les paramètres, et peut-être aussi pour ce qui classe particulière d'événements que la fonction de rappel doit être invoquée.
Le "répartiteur d'évènement" reçoit les événements de l'O/S (ou GUI, etc), et appelle en fait les rappels, par la recherche dans une liste de rappels pour voir qui sont intéressés par cet événement.
oui, c'est le répartiteur, et de loin la plus banale possible.
OriginalL'auteur Alnitak
Sans la sortie du compilateur, c'est dur, mais je peux en voir quelques-uns des problèmes;
Devrait être
La
my_custom_data
variable n'existe pas lorsqu'il est utilisé ici;Ce pointeur n'est jamais initialisée;
Et dans;
Vous ne pouvez pas passer le nom d'un type ("événement") à une fonction, vous devez passer une instance de ce type.
OriginalL'auteur Andrew Grant
Qu'est-ce que ce type
event_ct_t
? Voulez-vous direevent_cb_t
?Crée un pointeur non initialisé à une structure
event_cb
. Remarque surtout cette points à la poubelle.Que vous essayez d'appeler des ordures. Vous avez besoin d'initialisation:
ou certains de ces trucs.
OriginalL'auteur dirkgently
Enregistrant un rappel signifie que vous spécifiez quelle fonction doit être appelée lorsque l'événement d'intérêt. Fondamentalement, vous êtes le réglage de la fonction de pointeur lors de l'enregistrement d'un rappel.
OriginalL'auteur Trent
Vous avez créé un pointeur de la structure, vous avez déclaré, mais il ne pointe pas vers quoi que ce soit:
Vous devez juste créer un type de votre structure:
puis passer son adresse à l'fonctions.
OriginalL'auteur jramirez