Memberfunctionpointer C++
-
Tach zusammen
Folgender C++ Code möchte ich zum laufen bringen :ETHWrapper.h (ANSI-C) ----------------- typedef void (t_handleDSAP) (t_Large_ethFrame); INT8 regDSAPListener(t_handleDSAP handl); ErrorHandler.h,cpp ------------------ class ErrorHandler{ ErrorHandler(ETHWrapper* eth); void handleDSAP(t_Large_ethFrame ethFrame); }; void ErrorHandler::handleDSAP(t_Large_ethFrame frame){ //call other c++ ErrorHandler- Memberfunction } ErrorHandler::ErrorHandler(ETHWrapper* eth){ //Hier tritt das Problem auf t_handleDSAP* handle=&handleDSAP; eth->regDSAPListener(handle); }Ich habe es schon damit versucht die zu registrierende Function
static zu machen "static void handleDSAP(t_Large_ethFrame ethFrame);" . Danach habe ich aber das Problem, dass ich aus dieser Methode keine Methode eines ErrorHandlers-Objekts aufrufen kann.
Habe im Netz auch Lösungen mit Templates gefunden, welche ich leider nicht einsetzten kann, da die zu registrierende Funktion später aus einer C-Funktion aufgerufen werden soll.
Deshalb muss es irgendeine andere Lösung geben.
Ich hoffe ihr könnt mir weiterhelfengruss,
roger
-
Member-Funktionen haben noch einen impliziten this-Parameter, deshalb können sie so schlecht an C übergeben werden. Da benötigst du eine Wrapper-Funktion drumherum (global oder statisch), die selber das richtige Objekt kennt, z.B.:
static void ErrorHandler::handleDSAP(t_Large_ethFrame ethFrame) { static ErrorHandler eh; eh.doSomething(); }
-
Hallo CStoll
Vielen dank für die rasche Antwort !Eigentlich möchte ich das ganze ohne static lösen, da ich mir so sonst einen Singelton einbaue. Gibt es keine Möglichkeit bsw. mit einer Art dynamic_cast für Funktionen ?
[cpp]
ErrorHandler.h,cpp
------------------class ErrorHandler{
ErrorHandler(ETHWrapper* eth);
void handleDSAP(t_Large_ethFrame ethFrame);
void writeError(string s);
};void ErrorHandler::writeError(string s){
...
}
void ErrorHandler::handleDSAP(t_Large_ethFrame frame){
writeError(frame.error);}ErrorHandler::ErrorHandler(ETHWrapper* eth){
//Hier tritt das Problem auf
t_handleDSAP* handle=&handleDSAP;
eth->regDSAPListener(handle);
}
[/cpp]
-
Da es sich um einen C-Aufruf handelt, hast Du mit "puren" Methodenzeigern keine Chance.
Du musst aus dem Argument, mit dem der Errorhandler aufgerufen wird, irgendwie wieder
auf das Objekt schließen können. (Ich gehe jetzt mal davon aus, dass es sinnvoll ist,
mehrere verschiedene ErrorHandler-Objekte zu haben - anderenfalls: Singleton)Dazu kannst Du dir einen Dispatcher schreiben, der aus dem Argument, dass die Fehler-
behandlungsroutine liefert, das passende Errorhandler-Objekt ermittelt. Voraussetzung dafür:
Das Argument enthält überhaupt Informationen, um dies zu tun. Anderenfalls bist Du
aufgeschmissen.Was für einen Rückgabewert liefert denn die Registrierungsroutine für den Fehlerhandler?
Als Rückgabewert ist ja ein INT8 angegeben.Vielleicht ist der Rückgabewert eine Art Handle. Dann könntest Du im Fehlerhandler
sowas in der Art machen (Pseudocode):void errHandler( ... frame)
{
res = handle_container.find( frame.handle); // Handle vom Registrierungsaufruf suchen
/// wenn handle_container z.B. eine Map ist, könnte er paare von Handles und Pointern
/// auf Errhandler-Objekte speichern. handle_container muss dann aber static (pfui)
/// sein oder in einem Singleton liegen
res.call( frame);
}
-
Hallo 7H3 N4C3R
Danke fuer die Antwort !Schade, ich hatte eigendlich gehofft es gäbe so eine "Brute Force" Methode, die einen Functionpointer erzeugen könnte. Ich werde es nun halt mit einer Zwischenklasse, die wie du es vorgeschlagen hast, die die Objekte verwaltet und entspr. aufruft, wenn eine Mitteilung für sie eintrifft.
Danke nochmals
Gruss,
Borowski