Callback Funktion C++

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
stardust5383
Beiträge: 28
Registriert: 31. Oktober 2009 10:36

Callback Funktion C++

Beitrag von stardust5383 »

Hallo zusammen,

ich muss in einer Methode einen API Aufruf für Siemens Hardware ausführen. Der Aufruf ist wie folgt definiert:

Code: Alles auswählen

PNIO_UINT32 PNIO_controller_open(
PNIO_UINT32 CpIndex, //in
PNIO_UINT32 ExtPar, //in
PNIO_CBF cbf_rec_read_conf, //in
PNIO_CBF cbf_rec_write_conf, //in
PNIO_CBF cbf_alarm_ind, //in
PNIO_UINT32 * Handle //out
);
PNIO_CBF cbf_rec_read_conf, PNIO_CBF cbf_rec_write_conf und PNIO_CBF cbf_alarm_ind sind Callback Funktionen, die im Programmbeispiel (was jedoch nur in C verfügbar ist) mit

void cbf_rec_read_conf(...)

definiert sind und dann einfach mit cbf_rec_read_conf in die Methode eingegeben werden. Unter C++ funktioniert das ja meines Wissens nicht so einfach mit den Funktionszeigern. Da ich nicht einfach eine Callback Klasse schreiben kann, die einen Caller zur Verfügung stellt, stehe ich etwas auf dem Schlauch, wie ich das dennoch realisieren kann?! Hat einer eine idee für mich?
fussel
Beiträge: 11
Registriert: 16. August 2004 19:29
Wohnort: OS

Beitrag von fussel »

Eigentlich sollte das in C++ doch genau so funktionieren wie in deinem C - Beispiel.
stardust5383
Beiträge: 28
Registriert: 31. Oktober 2009 10:36

Beitrag von stardust5383 »

das dachte ich auch erst... leider aber gibt der Compiler eine Fehlermeldung. Hab schon ein wenig gegoogelt und gelesen, dass in C++ Callbacks nicht so funktionieren wie unter C wegen den Objekten (this). Wäre ein Interface die Lösung?
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Du kannst halt keine Member-Funktionen als Callback mitgeben. Für solche Sachen gibt es in den Callbacks aber (hoffentlich auch bei Siemens) einen "void* UserData" (hatten wir hier kürzlich schon im Forum). Du kannst für das UserData jetzt einen Zeiger auf eine Instanz deiner Klasse übergeben, und in dem eigentlichen Callback wieder auf Pointer-auf-meine-Klasse zurückcasten.

Den eigentlichen Callback musst du aber in extern "C" packen! Zeig mal auf ein Minimum reduzierten Code (deinen Callback, die Verwendung der Funktion, und was dafür sonst noch wichtig ist).

// edit:
Link zu Thread eingefügt
stardust5383
Beiträge: 28
Registriert: 31. Oktober 2009 10:36

Beitrag von stardust5383 »

@franzf: Das hört sich plausibel an, nur fällt es mir imo schwer vorzustellen. Ich packe morgen früh mal einen Ausschnitt meiner Klasse hier rein für die weitere Struktur. Grundsätzlich hab ich eine Klasse PNIOStack geschrieben, die Methoden enthält wie initalize() und uninitialize(). Als private attribute gibt es das devicehandle, welches nach dem Aufruf der besagten Funktion controller_open in der Methode initialize() gesetzt wird.

Im Callback muss ich ja ieine referenz auf dieses Objekt haben?! vllt kannst du deinen vorschlag ein wenig anders erklären :)

danke dir.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

stardust5383 hat geschrieben:Grundsätzlich hab ich eine Klasse PNIOStack geschrieben, die Methoden enthält wie initalize() und uninitialize().
Eine Klasse hat kein initialize() und uninitialize() - dafür gibts Konstruktor und Destruktor!
Im Callback muss ich ja ieine referenz auf dieses Objekt haben?! vllt kannst du deinen vorschlag ein wenig anders erklären :)
Ich hab den anderen Thread verlinkt, da siehst du ein Beispiel, wie du in dem Callback via void* UserData zu deiner Klasseninstanz kommst.
stardust5383
Beiträge: 28
Registriert: 31. Oktober 2009 10:36

Beitrag von stardust5383 »

ok, die methodennamen sind vllt ein wenig irreführend, aber initialize startet meine Verbindung. Die eigentliche Initialisierung erfolgt wie gewohnt im Konstruktor.
Antworten