C++

Callback-functie in C++

Callback-functie in C++

Een callback-functie is een functie, die een argument is, geen parameter, in een andere functie. De andere functie kan de hoofdfunctie worden genoemd. Er zijn dus twee functies bij betrokken: de hoofdfunctie en de callback-functie zelf. In de parameterlijst van de hoofdfunctie is de declaratie van de callback-functie zonder zijn definitie aanwezig, net zoals objectdeclaraties zonder toewijzing aanwezig zijn. De hoofdfunctie wordt aangeroepen met argumenten (in main()). Een van de argumenten in de hoofdfunctie-aanroep is de effectieve definitie van de callback-functie. In C++ is dit argument een verwijzing naar de definitie van de callback-functie; het is niet de werkelijke definitie. De callback-functie zelf wordt eigenlijk aangeroepen binnen de definitie van de hoofdfunctie.

De basis callback-functie in C++ garandeert geen asynchroon gedrag in een programma.  Asynchroon gedrag is het echte voordeel van het callback-functieschema. In het asynchrone callback-functieschema moet het resultaat van de hoofdfunctie voor het programma worden verkregen voordat het resultaat van de callback-functie wordt verkregen. Het is mogelijk om dit te doen in C++; C++ heeft echter een bibliotheek genaamd future om het gedrag van het asynchrone callback-functieschema te garanderen.

In dit artikel wordt het basisschema van de callback-functie uitgelegd:. Veel ervan is met pure C++. Wat het terugbellen betreft, wordt ook het basisgedrag van de toekomstige bibliotheek uitgelegd. Basiskennis van C++ en zijn aanwijzingen is noodzakelijk voor het begrijpen van dit artikel.

Artikel Inhoud

Basis terugbelfunctieschema

Een callback-functieschema heeft een hoofdfunctie nodig, en de callback-functie zelf. De declaratie van de callback-functie maakt deel uit van de parameterlijst van de hoofdfunctie. De definitie van de callback-functie wordt aangegeven in de functie-aanroep van de hoofdfunctie. De callback-functie wordt eigenlijk aangeroepen binnen de definitie van de hoofdfunctie. Het volgende programma illustreert dit:

#include
namespace std; gebruiken;
int principalFn(char ch[], int (*ptr)(int))

int id1 = 1;
int id2 = 2;
int idr = (*ptr)(id2);
cout<<"principal function: "<retour id1;

int cb(int iden)

cout<<"callback function"<<'\n';
retour ident;

int hoofd()

int (*ptr)(int) = &cb;
char cha[] = "en";
principalFn(cha, cb);
retourneer 0;

De uitvoer is:

terugbelfunctie
hoofdfunctie: 1 en 2

De hoofdfunctie wordt geïdentificeerd door principalFn(). De callback-functie wordt geïdentificeerd door cb(). De callback-functie wordt gedefinieerd buiten de hoofdfunctie, maar wordt daadwerkelijk binnen de hoofdfunctie aangeroepen.

Let op de declaratie van de callback-functie als parameter in de parameterlijst van de principal-functiedeclaratie. De verklaring van de callback-functie is "int (*ptr)(int)". Let op de callback-functie-expressie, zoals een functieaanroep, in de definitie van de hoofdfunctie; elk argument voor de callback-functieaanroep wordt daar doorgegeven. De instructie voor deze functieaanroep is:

int idr = (*ptr)(id2);

Waar id2 een argument is. ptr maakt deel uit van de parameter, een pointer, die wordt gekoppeld aan de referentie van de callback-functie in de main()-functie.

Let op de uitdrukking:

int (*ptr)(int) = &cb;

In de functie main(), die de declaratie (zonder definitie) van de callback-functie koppelt aan de naam van de definitie van dezelfde callback-functie.

De hoofdfunctie wordt in de functie main() aangeroepen als:

principalFn(cha, cb);

Waar cha een string is en cb de naam is van de callback-functie zonder enig argument.

Synchroon gedrag van terugbelfunctie

Denk aan het volgende programma:

#include
namespace std; gebruiken;
void principalFn(void (*ptr)())

cout<<"principal function"<<'\n';
(*ptr)();

ongeldig cb()

cout<<"callback function"<<'\n';

ongeldig fn()

cout<<"seen"<<'\n';

int hoofd()

leegte (*ptr)() = &cb;
hoofdsomFn(cb);
fn();
retourneer 0;

De uitvoer is:

hoofdfunctie
terugbelfunctie
gezien

Er is een nieuwe functie hier. Het enige wat de nieuwe functie doet, is de output weergeven, "gezien". In de functie main() wordt de hoofdfunctie aangeroepen, daarna wordt de nieuwe functie fn() aangeroepen. De uitvoer laat zien dat de code voor de hoofdfunctie is uitgevoerd, vervolgens die voor de callback-functie en ten slotte die voor de functie fn(). Dit is synchroon (single-threaded) gedrag.

Als het asynchroon gedrag zou zijn, wanneer drie codesegmenten in volgorde worden aangeroepen, kan het eerste codesegment worden uitgevoerd, gevolgd door de uitvoering van het derde codesegment, voordat het tweede codesegment wordt uitgevoerd.

Welnu, de functie fn() kan als volgt worden aangeroepen vanuit de definitie van de hoofdfunctie, in plaats van vanuit de functie main():

#include
namespace std; gebruiken;
ongeldig fn()

cout<<"seen"<<'\n';

void principalFn(void (*ptr)())

cout<<"principal function"<<'\n';
fn();
(*ptr)();

ongeldig cb()

cout<<"callback function"<<'\n';

int hoofd()

leegte (*ptr)() = &cb;
hoofdsomFn(cb);
retourneer 0;

De uitvoer is:

hoofdfunctie
gezien
terugbelfunctie

Dit is een imitatie van asynchroon gedrag. Het is geen asynchroon gedrag. Het is nog steeds synchroon gedrag.

Ook kan de volgorde van uitvoering van het codesegment van de hoofdfunctie en het codesegment van de callback-functie worden verwisseld in de definitie van de hoofdfunctie. Het volgende programma illustreert dit:

#include
namespace std; gebruiken;
 
void principalFn(void (*ptr)())

(*ptr)();
cout<<"principal function"<<'\n';

ongeldig cb()

cout<<"callback function"<<'\n';

ongeldig fn()

cout<<"seen"<<'\n';

int hoofd()

leegte (*ptr)() = &cb;
hoofdsomFn(cb);
fn();
retourneer 0;

De uitvoer is nu,

terugbelfunctie
hoofdfunctie
gezien

Dit is ook een imitatie van asynchroon gedrag. Het is geen asynchroon gedrag. Het is nog steeds synchroon gedrag. Echt asynchroon gedrag kan worden verkregen zoals uitgelegd in de volgende sectie of met de bibliotheek, toekomst.

Asynchroon gedrag met terugbelfunctie

De pseudo-code voor het basisasynchrone callback-functieschema is:

soort uitgang;
type cb (type uitvoer)

//verklaringen

type principalFn (type invoer, type cb (type uitvoer))

//verklaringen

Let op de posities van de invoer- en uitvoergegevens op de verschillende plaatsen van de pseudo-code. De invoer van de callback-functie is de uitvoer ervan. De parameters van de hoofdfunctie zijn de invoerparameter voor de algemene code en de parameter voor de callback-functie. Met dit schema kan een derde functie worden uitgevoerd (aangeroepen) in de functie main() voordat de uitvoer van de callback-functie wordt gelezen (nog steeds in de functie main()). De volgende code illustreert dit:

#include
namespace std; gebruiken;
char * uitvoer;
void cb(char uit[])

uitgang = uit;

void principalFn(char input[], void (*ptr)(char[50]))

(*ptr)(invoer);
cout<<"principal function"<<'\n';

ongeldig fn()

cout<<"seen"<<'\n';

int hoofd()

char input[] = "callback-functie";
leegte (*ptr)(char[]) = &cb;
principalFn(invoer, cb);
fn();
cout<retourneer 0;

De programma-uitvoer is:

hoofdfunctie
gezien
terugbelfunctie

In deze specifieke code zijn de uitvoer- en invoerdatum toevallig dezelfde datum. Het resultaat van de derde functie-aanroep in de main()-functie is weergegeven vóór het resultaat van de callback-functie. De callback-functie is uitgevoerd, voltooid en heeft het resultaat (waarde) toegewezen aan de variabele output, waardoor het programma kan doorgaan zonder zijn interferentie. In de main()-functie werd de uitvoer van de callback-functie gebruikt (gelezen en weergegeven) wanneer dat nodig was, wat leidde tot asynchroon gedrag voor het hele schema.

Dit is de single-threaded manier om asynchroon gedrag van de callback-functie te verkrijgen met pure C++.

Basisgebruik van de toekomstige bibliotheek

Het idee van het asynchrone callback-functieschema is dat de hoofdfunctie terugkeert voordat de callback-functie terugkeert. Dit gebeurde indirect, effectief, in de bovenstaande code.

Merk op uit de bovenstaande code dat de callback-functie de hoofdinvoer voor de code ontvangt en de hoofduitvoer voor de code produceert. De C++-bibliotheek, future, heeft een functie genaamd sync(). Het eerste argument voor deze functie is de verwijzing naar de callback-functie; het tweede argument is de invoer voor de callback-functie. De functie sync() keert terug zonder te wachten tot de uitvoering van de callback-functie is voltooid, maar laat de callback-functie toe om te voltooien. Dit zorgt voor asynchroon gedrag. Terwijl de callback-functie doorgaat met het uitvoeren, aangezien de sync()-functie al is teruggekeerd, blijven de onderstaande instructies worden uitgevoerd. Dit is als ideaal asynchroon gedrag.

Het bovenstaande programma is hieronder herschreven, rekening houdend met de toekomstige bibliotheek en zijn sync()-functie:

#include
#include
#include
namespace std; gebruiken;
toekomst uitgang;
string cb(string stri)

retour streep;

void principalFn (tekenreeksinvoer)

output = asynchrone (cb, input);
cout<<"principal function"<<'\n';

ongeldig fn()

cout<<"seen"<<'\n';

int hoofd()

string invoer = string ("callback-functie");
principalFn(invoer);
fn();
string ret = uitvoer.krijgen(); // wacht op terugbellen om terug te komen indien nodig
cout<retourneer 0;

De functie sync() slaat uiteindelijk de uitvoer van de callback-functie op in het toekomstige object. De verwachte output kan worden verkregen in de main()-functie, met behulp van de get()-lidfunctie van het toekomstige object.

Conclusie

Een callback-functie is een functie, die een argument is, geen parameter, in een andere functie. Een callback-functieschema heeft een hoofdfunctie nodig, en de callback-functie zelf. De declaratie van de callback-functie maakt deel uit van de parameterlijst van de hoofdfunctie. De definitie van de callback-functie wordt aangegeven in de functie-aanroep van de principal-functie (in main()). De callback-functie wordt eigenlijk aangeroepen binnen de definitie van de hoofdfunctie.

Een callback-functieschema is niet noodzakelijk asynchroon. Om er zeker van te zijn dat het callback-functieschema asynchroon is, voert u de hoofdinvoer naar de code uit, de invoer naar de callback-functie; maak de hoofduitvoer van de code, de uitvoer van de callback-functie; sla de uitvoer van de callback-functie op in een variabele of datastructuur. Voer in de functie main() na het aanroepen van de hoofdfunctie andere instructies van de toepassing uit. Wanneer de uitvoer van de callback-functie nodig is, in de main()-functie, gebruik (lees en toon) het daar en dan.

Hoe League Of Legends op Ubuntu 14 te installeren.04
Als je fan bent van League of Legends, dan is dit een kans voor jou om League of Legends te testen. Merk op dat LOL wordt ondersteund op PlayOnLinux a...
Installeer de nieuwste OpenRA Strategy Game op Ubuntu Linux
OpenRA is een Libre/Free Real Time Strategy-game-engine die de vroege Westwood-games nabootst, zoals de klassieke Command & Conquer: Red Alert. Gedist...
Installeer de nieuwste Dolphin Emulator voor Gamecube & Wii op Linux
Met de Dolphin Emulator kun je de door jou gekozen Gamecube- en Wii-spellen spelen op Linux Personal Computers (pc). Omdat het een vrij beschikbare e...