2016-04-16 14 views
1

In einem C++ - Projekt verwende ich eine C-Bibliothek für den Zugriff auf einige Hardware. Die C-Bindings enthalten Rückrufe, um über Änderungen an einigen Eingangspins zu informieren. Die Funktion für den Rückruf sieht wie folgt aus: void callback(char port, uint8_t interrupt_mask, uint8_t value_mask, void *user_data)Zuordnung von C++ - Memberfunktion zu C-Callback

In meiner Implementierung Ich habe eine SensorController Klasse, die eine Elementfunktion hat, die den Rückruf erhalten soll. Die Elementfunktion sieht folgendermaßen aus: void SensorController::pinChanged(char port, uint8_t interrupt_mask, uint8_t value_mask, void *user_data).

Jetzt fragte ich mich, was wäre der sauberste Weg zu vermeiden, die pinChanged Funktion statisch zu machen, um die Funktion dem Rückruf zuweisen zu können?

Antwort

5

Verwenden Sie den Zeiger user_data, um Ihnen einen Zeiger auf die Klasse zurückzugeben, die den Rückruf besitzt. Beispielsweise.

void MyCallback(char port, uint8_t interrupt_mask, uint8_t value_mask, void *user_data) 
{ 
    static_cast<Example *>(user_data)->Callback(port, interrupt_mask, value_mask); 
} 

class Example 
{ 
public: 

    Example() 
    { 
     //setup callback here - i dont know what library you're using but you should be able to pass a this pointer as user_data 
     init_lib(fictionalparameter1, fictionalparameter2, this); 
    } 

private: 

    void Callback(char port, uint8_t interrupt_mask, uint8_t value_mask) 
    { 
     //callback handler here... 
    } 

    friend void MyCallback(char port, uint8_t interrupt_mask, uint8_t value_mask, void *user_data); 
}; 
+0

Ja, genau. Das ist der springende Punkt beim Bereitstellen eines Benutzerkontextzeigerarguments. –

+0

Sie sollten static_cast verwenden (reinterpret_cast ist implementierungsdefiniert). – Adam

0

Funktion, die Callback nur empfängt sein kann:

  1. Ordinary Funktion
  2. Statische Funktion

Warum es kein Mitglied der Klasse Funktion sein kann?

Es geht nur um Zeiger. Der Zeiger auf normale Funktion oder statische Funktion ist eine Adresse zum Speicher. Zeiger auf eine Member - Klassenfunktion ist eine Offset - Nummer, die zum Objektzeiger (this) hinzugefügt werden soll, um auf die Methode zuzugreifen. [siehe JV110 comment]

In C++, Elementfunktionen haben einen impliziten Parameter, um das Objekt zu Punkten (den diesen Zeiger in der Elementfunktion). Normale C Funktionen können mit einer anderen Aufrufkonvention von Elementfunktionen gedacht werden, so dass die Typen ihrer Zeiger (Zeiger-zu-Element-Funktion vs Zeiger auf Funktion) sind unterschiedlich und inkompatibel. C++ führt einen neuen Typ von Zeiger ein, der als Zeiger-zu-Mitglied bezeichnet wird, der nur durch Bereitstellen eines Objekts aufgerufen werden kann. https://isocpp.org/wiki/faq/pointers-to-members#addr-of-memfn

könnten Sie in Rückruf verwenden user_data Klasse Member-Methoden zugreifen wie die user1320881.

+1

Nein, nur Zeiger auf Mitglieder _nun-function_ sind Offsets. Mitgliederfunktionen sind keine wirklichen Mitglieder, das ist eine riesige Verschwendung von Speicher. Sie sind wie statische Funktionen, benötigen aber einen impliziten "this" -Parameter – jv110