IMemInputPin::Receive zu eigener Funktion umleiten
-
Hallo,
ich möchte Bilder, die mittels Directshow und einer Webcam aufgenommen werden, vor dem Rendern verändern können.
Dazu möchte ich die Funktion IMemInputPin::Receive auf eine eigene Funktion umleiten.
Dazu habe ich bereits ein funktionierendes Beispiel im Internet gefunden (Quelle)- hier die wichtigen Teile:#define DsHook(a,b,c) if (!c##_) { INT_PTR* p=b+*(INT_PTR**)a; VirtualProtect(&c##_,4,PAGE_EXECUTE_READWRITE,&no);\ *(INT_PTR*)&c##_=*p; VirtualProtect(p, 4,PAGE_EXECUTE_READWRITE,&no); *p=(INT_PTR)c; } HRESULT ( __stdcall * Receive_ ) ( void* inst, IMediaSample *smp ) ; HRESULT __stdcall Receive ( void* inst, IMediaSample *smp ) { //Hier kann mein Code zum Verändern des Bildes hin. HRESULT ret = Receive_ ( inst, smp ); return ret; } IMemInputPin* mem = 0; hr = pin->QueryInterface(IID_IMemInputPin,(void**)&mem); DsHook(mem,6,Receive); // funktion umleiten..
Nun möchte ich aber, dass meine Receive-Funktion die Memberfunktion einer Klasse ist. Also
class Blub{ HRESULT __stdcall Receive ( void* inst, IMediaSample *smp ){ //Hier kann mein Code zum Verändern des Bildes hin. HRESULT ret = Receive_ ( inst, smp ); return ret; } }
somit funktioniert leider
Blub* inst=new Blub();
DsHook(mem,6,inst->Receive)nicht :(.
Hat jemand einen Rat, wie ich das zum Laufen bringen könnte ?
-
Hallo Amburu,
das geht leider nicht.
Du kannst zu einer Memberfunktion keinen Zeiger bekommen da sie eine anderere Signatur aufweisen. Eine Memberfunktion muss schließlich wissen wo ihre Daten sind und dazu braucht sie this Zeiger.
(auch wichtig an der Stelle zu wissen http://de.wikipedia.org/wiki/Aufrufkonvention#thiscall)Um jedoch deine Memberfunktion aufzurufen zu können, muss du eine andere Funktion aufrufen, welche weiß welches Objekt z.B. zu void* inst dazu gehört.
In deinem Objekt musst du dann einen void* inst als member haben.
Dem weist du den initialisierten (IMemInputPin* mem) Zeiger zu. Und schon hast du eine eindeutige Verbindung.
Dann musst du dein Objekt irgedwo global registrieren (z.B. in einen vector).Nun rufst du in Receive die Funktion auf die über (void * inst) den entsprechenden Partner findet und deine Memberfunktion aufruft.
So habe ich es zumindest gemacht.