ProgrammationDéveloppeur Embedded C

Décrivez comment les fonctions de rappel (callback functions) sont mises en œuvre et fonctionnent dans le langage C. Comment déclarer et utiliser correctement ces fonctions lors du développement de bibliothèques ou de l'interaction avec des API ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

Les fonctions de rappel (callbacks) sont des fonctions dont l'adresse est passée comme argument à une autre fonction. Cela permet de réaliser des gestionnaires d'événements, des algorithmes personnalisés et des plugins.

Déclaration d'une fonction callback :

  1. Décrire le type correspondant du pointeur sur fonction :
typedef void (*callback_func_t)(int);
  1. Passer la fonction de gestion :
void process(callback_func_t cb) { // ... cb(42); // appel callback } void handler(int n) { printf("Nombre traité : %d ", n); } int main() { process(handler); return 0; }

Conseils :

  • Respectez le typedef explicite pour les types de pointeurs, le code sera plus lisible.
  • Assurez-vous que la signature de la fonction callback correspond à celle attendue.
  • Évitez de passer des fonctions locales non initialisées ou libérées.

Question piège

Peut-on passer une fonction avec une signature non correspondante comme callback ?

Réponse erronée fréquente : « Oui, C le permettra si vous déclarez un cast explicite ».

Réponse correcte : Bien que le cast formel soit possible, appeler une telle fonction entraînera un comportement indéfini - des valeurs incorrectes peuvent être passées aux paramètres, la pile peut être corrompue.

Exemple de danger :

typedef void (*cb_t)(int); void wrong_cb(double d) { printf("%f ", d); } void call(cb_t f) { f(123); } int main() { call((cb_t)wrong_cb); } // DANGEREUX : les signatures divergent

Exemples d'erreurs réelles dues à l'incompréhension des subtilités du sujet


Histoire

Dans un projet embarqué, la fonction de tri a reçu un pointeur vers une fonction de comparaison avec une signature trop étroite. Cela a conduit à des erreurs de tri et à des corruptions de mémoire dues à un passage incorrect des paramètres.

Histoire

Dans la bibliothèque d'un moteur graphique, un mécanisme d'événements basé sur des callbacks a été mis en œuvre, mais certains callbacks faisaient accidentellement référence à des fonctions locales de bibliothèques dynamiques déjà libérées, ce qui provoquait des plantages lors de la rencontre avec des adresses invalides.

Histoire

Lors du développement d'un système multiplateforme, l'auteur a mal défini la convention d'appel pour les fonctions callback. Cela ne se manifestait pas sur un système d'exploitation, mais entraînait un crash du programme sur un autre lors de l'appel des callbacks depuis une bibliothèque C.