In programmazione, una callback o richiamo è generalmente una funzione o un "blocco di codice" che viene passato come parametro a un'altra funzione. In particolare, quando ci si riferisce alla callback richiamata da una funzione, la callback viene passata come argomento ad un parametro della funzione chiamante. In questo modo la chiamante può realizzare un compito specifico (quello svolto dalla callback) che non è, molto spesso, noto al momento della scrittura del codice.

Se invece ci si riferisce alla callback come funzione richiamata dal sistema operativo, di norma ciò si utilizza allo scopo di gestire particolari eventi: dal premere un bottone con il mouse, allo scrivere caratteri in un campo di testo. Ciò consente, quindi, a un programma di livello più basso, di richiamare una funzione (o servizio) definita a un livello più alto.

Esempi modifica

Le callback hanno molti campi d'applicazione. Un esempio pratico di funzione che richiede una callback tra i parametri è la funzione qsort della libreria standard del C. La qsort implementa l'algoritmo di ordinamento quicksort e può essere utilizzata per ordinare un array contenente qualsiasi tipo di dato, a patto che l'array risieda completamente in memoria.

Il seguente frammento di codice ordina una ipotetica lista di soldati per grado e per nome. In questo esempio:

  • la funzione callback è la ConfrontaSoldati che sa come confrontare i soldati, ma non sa nulla di ordinamento
  • la funzione generica è la qsort che non sa cosa sta ordinando, ma conoscendo le dimensioni dell'array e chiamando ripetutamente la funzione callback riesce a fare i giusti scambi per mettere in ordine l'array.
#include <stdlib.h>
#include <string.h>

#define QUANTI_SOLDATI 100

struct TSoldato {
    int grado;
    char nome[80];
} Esercito[QUANTI_SOLDATI];

int ConfrontaSoldati(const void *ptr1, const void *ptr2)
{
    const TSoldato *s1=(const TSoldato*)ptr1; // GNU GCC Compiler necessita della parola chiave "const" prima di TSoldato
                                              //     sia a sinistra che a destra dell'operatore di assegnazione
    const TSoldato *s2=(const TSoldato*)ptr2; // come sopra

    if(s1->grado!=s2->grado)
        return s1->grado - s2->grado;

    return strcmp(s1->nome, s2->nome);
}

void OrdinaEsercito()
{
    qsort(Esercito, QUANTI_SOLDATI, sizeof(const TSoldato), ConfrontaSoldati); // come sopra, all'interno della 'sizeof' prima di TSoldato 
                                                                         //    scrivere la parola chiave "const"
}

Da notare che i parametri della qsort sono rispettivamente: la base dell'array, la quantità di elementi presenti, la dimensione di ciascun elemento e la funzione di callback ConfrontaSoldati.

Il secondo esempio è un codice in C che illustra l'uso di callback per mostrare 2 numeri:

#include <stdio.h>
#include <stdlib.h>

/* La funzione chiamante riceve come parametro una singola callback */
void PrintTwoNumbers(int (*numberSource)(void)) {
    printf("%d and %d\n", numberSource(), numberSource());
}
 
/* Una possibile callback */
int overNineThousand(void) {
    return (rand() % 1000) + 9000;
}

/* Un'altra possibile callback */
int fortyTwo(void) {
    return 42;
}
 
/* Viene chiamata la funzione PrintTwoNumbers() con 3 differenti callback */
int main(void) {
    PrintTwoNumbers(rand);
    PrintTwoNumbers(overNineThousand);
    PrintTwoNumbers(fortyTwo);
}

L'output dovrebbe essere qualcosa di simile:

 125185 and 89188225
 9084 and 9441
 42 and 42

Si noti come sia più utile passare la funzione di callback alla chiamante, PrintTwoNumbers(), piuttosto che stampare sempre lo stesso valore. La PrintTwoNumbers chiama la callback per tante volte quanto è richiesto. Questo è uno dei due vantaggi delle callback.

Il secondo vantaggio è che la funzione chiamante può passare qualsiasi parametro alle funzioni callback chiamate. Questo implementa correttamente l'information hiding: il codice client che passa una callback alla funzione chiamante non è necessario che conosca i parametri della callback. Se invece passasse alla chiamante il solo valore restituito dalla callback, esso sarebbe esposto pubblicamente. In questo caso, information hiding significa che le callback possono essere utilizzate per comunicare messaggi e dati tra processi, o tra thread, o per inviare comunicazioni serializzate, in rete o altre.

Voci correlate modifica

  Portale Informatica: accedi alle voci di Wikipedia che trattano di informatica