Seite 1 von 1

Callback Funktion C++

Verfasst: 15. September 2010 13:26
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?

Verfasst: 15. September 2010 14:33
von fussel
Eigentlich sollte das in C++ doch genau so funktionieren wie in deinem C - Beispiel.

Verfasst: 15. September 2010 15:02
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?

Verfasst: 15. September 2010 15:44
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

Verfasst: 15. September 2010 15:55
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.

Verfasst: 16. September 2010 08:38
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.

Verfasst: 16. September 2010 08:44
von stardust5383
ok, die methodennamen sind vllt ein wenig irreführend, aber initialize startet meine Verbindung. Die eigentliche Initialisierung erfolgt wie gewohnt im Konstruktor.