Eine Callback-Funktion ist eine Funktion, die ein Argument, kein Parameter, in einer anderen Funktion ist. Die andere Funktion kann als Hauptfunktion bezeichnet werden. Es sind also zwei Funktionen beteiligt: die Principal-Funktion und die Callback-Funktion selbst. In der Parameterliste der Principal-Funktion ist die Deklaration der Callback-Funktion ohne ihre Definition vorhanden, ebenso wie Objektdeklarationen ohne Zuweisung vorhanden sind. Die Principal-Funktion wird mit Argumenten aufgerufen (in main()). Eines der Argumente im Hauptfunktionsaufruf ist die effektive Definition der Rückruffunktion. In C++ ist dieses Argument ein Verweis auf die Definition der Callback-Funktion; es ist nicht die eigentliche Definition. Die Callback-Funktion selbst wird tatsächlich innerhalb der Definition der Principal-Funktion aufgerufen.
Die grundlegende Callback-Funktion in C++ garantiert kein asynchrones Verhalten in einem Programm. Asynchrones Verhalten ist der wahre Vorteil des Callback-Funktionsschemas. Beim asynchronen Callback-Funktionsschema sollte das Ergebnis der Principal-Funktion für das Programm abgerufen werden, bevor das Ergebnis der Callback-Funktion abgerufen wird. Dies ist in C++ möglich; C++ verfügt jedoch über eine Bibliothek namens future, um das Verhalten des asynchronen Callback-Funktionsschemas zu gewährleisten.
Dieser Artikel erklärt das grundlegende Schema der Rückruffunktion. Vieles davon ist mit reinem C++. Was den Callback angeht, wird auch das grundsätzliche Verhalten der zukünftigen Bibliothek erklärt. Für das Verständnis dieses Artikels sind Grundkenntnisse in C++ und seinen Pointern erforderlich.
Artikelinhalt
- Grundlegendes Schema der Rückruffunktion
- Synchrones Verhalten mit Callback-Funktion
- Asynchrones Verhalten mit Callback-Funktion
- Grundlegende Nutzung der zukünftigen Bibliothek
- Fazit
Grundlegendes Schema der Rückruffunktion
Ein Callback-Funktionsschema benötigt eine Principal-Funktion und die Callback-Funktion selbst. Die Deklaration der Callback-Funktion ist Teil der Parameterliste der Principal-Funktion. Die Definition der Callback-Funktion ist im Funktionsaufruf der Principal-Funktion angegeben. Die Callback-Funktion wird tatsächlich innerhalb der Definition der Principal-Funktion aufgerufen. Das folgende Programm veranschaulicht dies:
#einschließenVerwenden von Namespace-Std;
int PrincipalFn(char ch[], int (*ptr)(int))
int-ID1 = 1;
int-ID2 = 2;
int idr = (*ptr)(id2);
cout<<"principal function: "<
int cb(int ident)
cout<<"callback function"<<'\n';
Rückgabe-ID;
int main()
int (*ptr)(int) = &cb;
char cha[] = "und";
PrincipalFn(cha, cb);
0 zurückgeben;
Die Ausgabe ist:
RückruffunktionHauptfunktion: 1 und 2
Die Principal-Funktion wird durch PrincipalFn() identifiziert. Die Callback-Funktion wird durch cb() identifiziert. Die Callback-Funktion wird außerhalb der Principal-Funktion definiert, aber tatsächlich innerhalb der Principal-Funktion aufgerufen.
Beachten Sie die Deklaration der Callback-Funktion als Parameter in der Parameterliste der Principal Function Deklaration. Die Deklaration der Callback-Funktion lautet „int (*ptr)(int)“. Beachten Sie den Callback-Funktionsausdruck wie einen Funktionsaufruf in der Definition der Prinzipalfunktion; jedes Argument für den Callback-Funktionsaufruf wird dort übergeben. Die Anweisung für diesen Funktionsaufruf lautet:
int idr = (*ptr)(id2);Wobei id2 ein Argument ist. ptr ist Teil des Parameters, ein Zeiger, der mit der Referenz der Callback-Funktion in der main()-Funktion verknüpft wird.
Beachten Sie den Ausdruck:
int (*ptr)(int) = &cb;In der Funktion main(), die die Deklaration (ohne Definition) der Callback-Funktion mit dem Namen der Definition derselben Callback-Funktion verknüpft links.
Die Hauptfunktion wird in der Funktion main() wie folgt aufgerufen:
PrincipalFn(cha, cb);Dabei ist cha ein String und cb der Name der Callback-Funktion ohne ihre Argumente.
Synchrones Verhalten der Callback-Funktion
Betrachten Sie das folgende Programm:
#einschließenVerwenden von Namespace-Std;
void PrincipalFn(void (*ptr)())
cout<<"principal function"<<'\n';
(*ptr)();
Leere cb()
cout<<"callback function"<<'\n';
Leere fn()
cout<<"seen"<<'\n';
int main()
Leere (*ptr)() = &cb;
HauptFn(cb);
fn();
0 zurückgeben;
Die Ausgabe ist:
HauptfunktionRückruffunktion
gesehen
Hier gibt es eine neue Funktion. Die neue Funktion zeigt lediglich die Ausgabe „gesehen“ an. In der Funktion main() wird die Hauptfunktion aufgerufen, dann wird die neue Funktion fn() aufgerufen. Die Ausgabe zeigt, dass der Code für die Principal-Funktion ausgeführt wurde, dann der für die Callback-Funktion und schließlich der für die fn()-Funktion. Dies ist synchrones (Single-Thread-) Verhalten.
Bei asynchronem Verhalten, wenn drei Codesegmente der Reihe nach aufgerufen werden, kann das erste Codesegment ausgeführt werden, gefolgt von der Ausführung des dritten Codesegments, bevor das zweite Codesegment ausgeführt wird.
Nun, die Funktion fn() kann aus der Definition der Hauptfunktion heraus aufgerufen werden, anstatt aus der main()-Funktion, wie folgt:
#einschließenVerwenden von Namespace-Std;
Leere fn()
cout<<"seen"<<'\n';
void PrincipalFn(void (*ptr)())
cout<<"principal function"<<'\n';
fn();
(*ptr)();
Leere cb()
cout<<"callback function"<<'\n';
int main()
Leere (*ptr)() = &cb;
HauptFn(cb);
0 zurückgeben;
Die Ausgabe ist:
Hauptfunktiongesehen
Rückruffunktion
Dies ist eine Imitation von asynchronem Verhalten. Es ist kein asynchrones Verhalten. Es ist immer noch synchrones Verhalten.
Außerdem kann die Ausführungsreihenfolge des Codesegments der Principal-Funktion und des Codesegments der Callback-Funktion in der Definition der Principal-Funktion vertauscht werden. Das folgende Programm veranschaulicht dies:
#einschließenVerwenden von Namespace-Std;
void PrincipalFn(void (*ptr)())
(*ptr)();
cout<<"principal function"<<'\n';
Leere cb()
cout<<"callback function"<<'\n';
Leere fn()
cout<<"seen"<<'\n';
int main()
Leere (*ptr)() = &cb;
HauptFn(cb);
fn();
0 zurückgeben;
Die Ausgabe ist jetzt,
RückruffunktionHauptfunktion
gesehen
Dies ist auch eine Imitation von asynchronem Verhalten. Es ist kein asynchrones Verhalten. Es ist immer noch synchrones Verhalten. Echtes asynchrones Verhalten kann wie im nächsten Abschnitt erläutert oder mit der Bibliothek zukünftig erreicht werden.
Asynchrones Verhalten mit Callback-Funktion
Der Pseudocode für das grundlegende asynchrone Callback-Funktionsschema lautet:
Typ Ausgabe;Typ cb (Typ Ausgang)
//Aussagen
Typ PrincipalFn (Typ Eingabe, Typ cb (Typ Ausgabe))
//Aussagen
Beachten Sie die Positionen der Ein- und Ausgabedaten an den verschiedenen Stellen des Pseudocodes. Die Eingabe der Callback-Funktion ist ihre Ausgabe. Die Parameter der Principal-Funktion sind der Input-Parameter für den Generalcode und der Parameter für die Callback-Funktion. Mit diesem Schema kann eine dritte Funktion in der main()-Funktion ausgeführt (aufgerufen) werden, bevor die Ausgabe der Callback-Funktion gelesen wird (noch in der main()-Funktion). Der folgende Code veranschaulicht dies:
#einschließenVerwenden von Namespace-Std;
char *Ausgabe;
void cb(char out[])
Ausgang = aus;
void PrincipalFn(char input[], void (*ptr)(char[50]))
(*ptr)(Eingabe);
cout<<"principal function"<<'\n';
Leere fn()
cout<<"seen"<<'\n';
int main()
char input[] = "Rückruffunktion";
void (*ptr)(char[]) = &cb;
PrincipalFn(Eingang, Cb);
fn();
cout<