146 votes

Qu'est-ce qu'un "callback" en C et comment sont-ils mis en œuvre ?

D'après mes lectures, Core Audio s'appuie fortement sur les callbacks (et sur C++, mais c'est une autre histoire).

Je comprends le concept (en quelque sorte) de la mise en place d'une fonction qui est appelée par une autre fonction de manière répétée pour accomplir une tâche. Je ne comprends pas comment elles sont mises en place et comment elles fonctionnent réellement. Tout exemple serait le bienvenu.

195voto

aib Points 18608

Il n'y a pas de "callback" en C - pas plus qu'aucun autre concept de programmation générique.

Ils sont mis en œuvre à l'aide de pointeurs de fonction. En 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, le populate_array prend un pointeur de fonction comme troisième paramètre et l'appelle pour obtenir les valeurs avec lesquelles le tableau doit être rempli. Nous avons écrit la fonction de rappel getNextRandomValue qui renvoie une valeur aléatoire, et transmet un pointeur vers cette valeur à populate_array . populate_array appellera notre fonction de rappel 10 fois et attribuera les valeurs retournées aux éléments du tableau donné.

118voto

Russell Bryant Points 623

Voici un exemple de callbacks en C.

Supposons que vous souhaitiez écrire un code qui permette d'enregistrer des rappels à appeler lorsqu'un événement se produit.

Définissez d'abord le type de fonction utilisé pour le rappel :

typedef void (*event_cb_t)(const struct event *evt, void *userdata);

Définissez maintenant une fonction utilisée pour enregistrer un rappel :

int event_cb_register(event_cb_t cb, void *userdata);

Voici à quoi ressemblerait un code qui enregistre un rappel :

static void my_event_cb(const struct event *evt, void *data)
{
    /* do stuff and things with the event */
}

...
   event_cb_register(my_event_cb, &my_custom_data);
...

Dans la partie interne du distributeur d'événements, le rappel peut être stocké dans une structure qui ressemble à ceci :

struct event_cb {
    event_cb_t cb;
    void *data;
};

Voici à quoi ressemble le code qui exécute un rappel.

struct event_cb *callback;

...

/* Get the event_cb that you want to execute */

callback->cb(event, callback->data);

19voto

Un simple programme de rappel. J'espère que cela répondra à votre question.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include "../../common_typedef.h"

typedef void (*call_back) (S32, S32);

void test_call_back(S32 a, S32 b)
{
    printf("In call back function, a:%d \t b:%d \n", a, b);
}

void call_callback_func(call_back back)
{
    S32 a = 5;
    S32 b = 7;

    back(a, b);
}

S32 main(S32 argc, S8 *argv[])
{
    S32 ret = SUCCESS;

    call_back back;

    back = test_call_back;

    call_callback_func(back);

    return ret;
}

4voto

John Millikin Points 86775

En C, les rappels sont généralement mis en œuvre à l'aide de pointeurs de fonction et d'un pointeur de données associé. Vous passez votre fonction on_event() et des pointeurs de données vers une fonction cadre watch_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 des interfaces graphiques. Les Tutoriel GTK contient une section intéressante sur la théorie des signaux et des rappels .

3voto

Leonard Points 2832

Le présent article de wikipedia présente un exemple en C.

Par exemple, les nouveaux modules écrits pour compléter le serveur web Apache s'enregistrent auprès du processus principal Apache en lui transmettant des pointeurs de fonction, de sorte que ces fonctions soient rappelées pour traiter les demandes de pages web.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X