ich habe eine dll, die in C-geschrieben ist. die dll hat eine Funktion mit Callback, in der man einen Funktionszeiger übergibt.
Leider kann ich jetzt nur eine globale Funktion aufrufen lassen, da meine c-dll keine Klassen objekte kennt.
Ich möchte aber, dass meine Klasse ein Signal auslöst, sobald die Callback-Funktion ausgelöst wird. Wie bekomme ich eine Verbindung zwischen der globalen Funktion und das Signal in der Klasse?
Das ist leider eine doofe Library. Denn normalerweise kommt bei einem C-Callback auch ein Parameter "void* UserData" mit. Demm könntest du deinen this-Zeiger mitgeben.
Aber so wie du das gepostet hast, geht es nicht.
Was für eine dll ist das denn? Kannst du die nicht wechseln? Oder dem Developer sagen, er soll doch bitte Konventionen einhalten, und einen UserData-Pointer mitnehmen?
ich habe jetzt den code der dll mir besorgt und soweit verstanden. wie kann ich nun diesen void* UserData einfügen und das this-Object übergeben? Gibt es ein Beispiel?
delegug hat geschrieben:ich habe jetzt den code der dll mir besorgt und soweit verstanden. wie kann ich nun diesen void* UserData einfügen und das this-Object übergeben? Gibt es ein Beispiel?
Was willst du denn jetzt machen? Die Lib anpassen? Oder gibt es doch einen Callback mit void* userdata?
#include <iostream>
typedef void (*CallBack)(int, void*);
// Das ist die Funktion, wie sie von der Library zur Verfügung gestellt wird.
void c_function_with_callback( int value, CallBack cb, void* user_data)
{
value *= 2;
cb(value, user_data);
}
struct Type {
// Das soll jetzt im Callback aufgerufen werden
void doIt(int value) {
std::cout << "Member Function Callback " << value << std::endl;
}
};
// Unsere Callback-Funktion, die an die Lib-Funktion übergeben wird.
void my_callback_fun(int value, void* data) {
Type* obj = static_cast<Type*>(obj);
obj->doIt(value);
}
int main() {
Type t;
c_function_with_callback(10, my_callback_fun, &t);
}
Für mehr Beispiele sollte google (z.B. nach "c++ c-callback user data") befragt werden.
ok, vielen dank. hab die lib angepasst und funktioniert mit übergabe des klassenobjekts und danach diesen casten.
hier noch ein hilfreicher link http://www.newty.de/fpt/callback.html
Zwei kurze Anmerkungen zu der Seite (scheint veraltet zu sein, jedenfalls aus C++-Sicht):
1) #include <iostream.h> gibt es nicht (mehr)! Das heißt jetzt nur "<iostream>
2) Casts im C-Style (wie auf der Seite) sollte man in C++ nicht machen, sie veschleiern was eigentlich wirklich passiert. C-Casts können sein
* static_cast
* reinterpret_cast
* const_cast
Bitte verwende immer die C++-Casts (auch wenn es etwas mehr Schreibaufwand ist), dann weißt du auch ganz genau, was da wirklich passiert, und bei einem cast-Fehler beschwert sich der Compiler!
Hier in dem Beispiel ist ein static_cast alles was du brauchst.
Wie bekomme ich eine Verbindung zwischen der globalen Funktion und das Signal in der Klasse?
Prinzipiell geht das aber auch.
gibt nur ein unschoenes Gebilde aus einer globalen Instanz einer klasse die statische Methoden auf Signale mappt. Oder man schreibt ne Proxy Dll, die das Interface anpasst und die "Clients" sauber verwaltet.
Die Loesung mit dem "Userdata" ist aber definitiv die elegantere und flexiblerer. Leider gibts noch paar Bib-Erzeuger, die das ned unterstuetzen. Dafuer muss man dann ganz schoen unsaubere oder umstaendliche Dinge in Kauf nehmen.