Il n'y a pas de "rappel" en C - pas plus que tout autre concept de programmation générique.
Ils sont implémentés à l'aide de pointeurs de fonction. Voici un exemple:
void populate_array(int *array, size_t arraySize, int (*getNextValue)(void))
{
for (size_t i=0; i<arraySize; i++)
array[i] = getNextValue();
}
int getNextRandomValue(void)
{
return rand();
}
int main(void)
{
int myarray[10];
populate_array(myarray, 10, getNextRandomValue);
...
}
Ici, la populate_array
fonction prend un pointeur de fonction comme troisième paramètre et l'appelle pour obtenir les valeurs avec lesquelles remplir le tableau. Nous avons écrit le rappel getNextRandomValue
, qui retourne une valeur aléatoire, et lui avons passé un pointeur vers populate_array
. populate_array
appellera notre fonction de rappel 10 fois et attribuera les valeurs renvoyées aux éléments du tableau donné.
Voici un exemple de callbacks en C.
Supposons que vous souhaitiez écrire du code permettant d'appeler les rappels d'enregistrement lorsqu'un événement se produit.
Définissez d'abord le type de fonction utilisée pour le rappel:
Maintenant, définissez une fonction qui est utilisée pour enregistrer un rappel:
Voici à quoi ressemblerait le code qui enregistre un rappel:
Dans les composants internes du répartiteur d'événements, le rappel peut être stocké dans une structure qui ressemble à ceci:
Voici à quoi ressemble le code qui exécute un rappel.
la source
libsrtp
ne donne aucun avertissement. Je présume, alors, que lorsqu'un tel type apparaît comme un argument de fonction, il est nécessaire de se `` désintégrer '' en un pointeur vers une fonction, tout comme les tableaux se désintègrent en pointeurs vers leurs premiers éléments, donc la même chose se produit à la fin d'une manière ou d'une autre. Il est intéressant, cependant, que les discussions sur ces typedefs que j'ai trouvées ne jettent même pas un coup d'œil sur cet aspect, mais se concentrent plutôt sur la déclaration de prototypes ou de pointeurs avecUn programme de rappel simple. J'espère que cela répond à votre question.
la source
Une fonction de rappel en C est l'équivalent d'un paramètre / variable de fonction assigné pour être utilisé dans une autre fonction.Exemple de wiki
Dans le code ci-dessous,
La fonction (* numberSource) à l'intérieur de l'appel de fonction PrintTwoNumbers est une fonction à «rappeler» / exécuter à partir de PrintTwoNumbers comme dicté par le code pendant qu'il s'exécute.
Donc, si vous aviez quelque chose comme une fonction pthread, vous pourriez assigner une autre fonction à exécuter à l'intérieur de la boucle à partir de son instanciation.
la source
Un rappel en C est une fonction qui est fournie à une autre fonction pour "rappeler" à un moment donné lorsque l'autre fonction exécute sa tâche.
Il y a deux façons d'utiliser un rappel : le rappel synchrone et le rappel asynchrone. Un rappel synchrone est fourni à une autre fonction qui va effectuer une tâche puis revenir à l'appelant avec la tâche terminée. Un rappel asynchrone est fourni à une autre fonction qui va démarrer une tâche puis revenir à l'appelant avec la tâche éventuellement non terminée.
Un rappel synchrone est généralement utilisé pour fournir un délégué à une autre fonction à laquelle l'autre fonction délègue une étape de la tâche. Des exemples classiques de cette délégation sont les fonctions
bsearch()
etqsort()
de la bibliothèque standard C. Ces deux fonctions prennent un rappel qui est utilisé pendant la tâche que la fonction fournit afin que le type des données recherchées, dans le cas debsearch()
, ou triées, dans le cas deqsort()
, n'ait pas besoin d'être connu par la fonction étant utilisé.Par exemple, voici un petit exemple de programme
bsearch()
utilisant différentes fonctions de comparaison, des rappels synchrones. En nous permettant de déléguer la comparaison des données à une fonction de rappel, labsearch()
fonction nous permet de décider au moment de l'exécution quel type de comparaison nous voulons utiliser. Ceci est synchrone car lorsque labsearch()
fonction retourne, la tâche est terminée.Un rappel asynchrone est différent en ce que lorsque la fonction appelée à laquelle nous fournissons un rappel revient, la tâche peut ne pas être terminée. Ce type de rappel est souvent utilisé avec les E / S asynchrones dans lesquelles une opération d'E / S est lancée, puis, une fois terminée, le rappel est appelé.
Dans le programme suivant, nous créons une socket pour écouter les demandes de connexion TCP et lorsqu'une demande est reçue, la fonction qui fait l'écoute appelle alors la fonction de rappel fournie. Cette application simple peut être exercée en l'exécutant dans une fenêtre tout en utilisant l'
telnet
utilitaire ou un navigateur Web pour tenter de se connecter dans une autre fenêtre.J'ai extrait la plupart du code WinSock de l'exemple fourni par Microsoft avec la
accept()
fonction à l' adresse https://msdn.microsoft.com/en-us/library/windows/desktop/ms737526(v=vs.85).aspxCette application démarre un
listen()
sur l'hôte local, 127.0.0.1, en utilisant le port 8282 afin que vous puissiez utiliser soittelnet 127.0.0.1 8282
ouhttp://127.0.0.1:8282/
.Cet exemple d'application a été créé en tant qu'application console avec Visual Studio 2017 Community Edition et utilise la version Microsoft WinSock des sockets. Pour une application Linux, les fonctions WinSock devraient être remplacées par les alternatives Linux et la bibliothèque de threads Windows utiliserait à la
pthreads
place.la source
Les rappels en C sont généralement implémentés à l'aide de pointeurs de fonction et d'un pointeur de données associé. Vous transmettez votre fonction
on_event()
et vos pointeurs de données à une fonction de cadrewatch_events()
(par exemple). Lorsqu'un événement se produit, votre fonction est appelée avec vos données et certaines données spécifiques à l'événement.Les rappels sont également utilisés dans la programmation GUI. Le tutoriel GTK + a une belle section sur la théorie des signaux et des rappels .
la source
Cet article de wikipedia a un exemple en C.
Un bon exemple est que les nouveaux modules écrits pour augmenter le registre du serveur Web Apache avec le processus apache principal en leur passant des pointeurs de fonction afin que ces fonctions soient rappelées pour traiter les requêtes de page Web.
la source
Habituellement, cela peut être fait en utilisant un pointeur de fonction, qui est une variable spéciale qui pointe vers l'emplacement mémoire d'une fonction. Vous pouvez ensuite l'utiliser pour appeler la fonction avec des arguments spécifiques. Il y aura donc probablement une fonction qui définit la fonction de rappel. Cela acceptera un pointeur de fonction, puis stockera cette adresse quelque part où elle pourra être utilisée. Après cela, lorsque l'événement spécifié est déclenché, il appellera cette fonction.
la source
Il est beaucoup plus facile de comprendre une idée par l'exemple. Ce qui a été dit sur la fonction de rappel en C jusqu'à présent sont d'excellentes réponses, mais probablement le plus grand avantage de l'utilisation de cette fonctionnalité est de garder le code propre et épuré.
Exemple
Le code C suivant implémente le tri rapide. La ligne la plus intéressante dans le code ci-dessous est celle-ci, où nous pouvons voir la fonction de rappel en action:
Compare_s2b est le nom de la fonction que qsort () utilise pour appeler la fonction. Cela garde qsort () si épuré (donc plus facile à maintenir). Vous appelez simplement une fonction par son nom depuis une autre fonction (bien sûr, la déclaration du prototype de fonction doit au moins précéder avant de pouvoir être appelée depuis une autre fonction).
Le code complet
la source