ISampleGrabber::SetCallback eigene Funktion übergeben
-
Hallo,
ich habe wieder einmal ein DirectShow Problem, und zwar gibt es eine Möglichkeit eine Callback Routine für Samples zu definieren, jedoch konnte ich nicht herausfinden, wie man alleine mit C eine eigene Callback-Routine definieren kann mein momentaner Aufruf:
Streamgrabber->SetCallback((ISampleGrabberCB *)grabSample, 1); HRESULT CALLBACK grabSample(double SampleTime, BYTE *pBuffer, long BufferLen) { MessageBox(NULL, TEXT("safas"), TEXT("saf"), 0); return S_OK; }führt zu einem Speicherzugriffsfehler(Funktionszeiger habe ich auch schon probiert, ledier mit dem gleichen Ergebniss).
vllt hat jemand eine Idee und kann mir helfen.
Mit freundlichen Grüßen
Anon
-
Casten ist immer schlecht... vermutlich musst Du hier ein IDispatch-Interface übergeben... aber das wirst Du sicher in der Doku zu den Methode finden...
-
Das Problem ist, dass bei MSDN nirgendwo ein Beispiel dazu zu finden ist, wie man eine eigene Callback-Funktion definiert. Dort stehen nur die Parameter. Und eine Klasse kann ich nicht implementieren, da ich auf reines C angewiesen bin. Allgemein bin ich was DirectShow angeht noch ziemlich neu.
Mit freundlichen Grüßen
Anon
-
Man kann ein COM-Interface auch in C schreiben; der Aufwand ist natürlich erheblich größer als in C++ mit ATL... ich kann Dir aber nicht mal ein Beispiel zeigen... müsste ich auch zuerst mal suchen, wie das nochmals geht...
-
Auf reines C bist Du scheinbar nicht angewiesen. Wie man an Deinem Syntax sieht verwendest Du schon C++.
Also implementiere nur das Inteerface in C++ (ATL,...).Ansonsten müsstest Du eine eigene Sprungtabele für alle Interface-Einträge aufbauen (inkl. AddRef, Release, QueryInterface).
Schau Dir mal das Beispiel für die GIT in Wine an, dass auch in C geschrieben würde:
http://wine.sourcearchive.com/documentation/1.1.5/git_8c-source.htmlSchrecklich in meinen Augen.
Nochmal wie Jochen es schon sagte: Mach es in C++!
-
In C++ könnte es so aussehen:
class CSampleGrabberCB : public ISampleGrabberCB { public: CSampleGrabberCB(); ~CSampleGrabberCB(); STDMETHODIMP QueryInterface(REFIID riid, void ** ppi); STDMETHODIMP SampleCB(double SampleTime, IMediaSample * pSample); STDMETHODIMP BufferCB(double SampleTime, BYTE * pBuffer, long BufferSize); STDMETHODIMP_ (ULONG) AddRef(); STDMETHODIMP_ (ULONG) Release(); ..... }; .. CSampleGrabberCB SG; CComPtr< ISampleGrabber > StreamGrabber; .. StreamGrabber.CoCreateInstance(CLSID_SampleGrabber); .. StreamGrabber->SetBufferSamples(false); StreamGrabber->SetOneShot(false); StreamGrabber->SetCallback(&SG, 0); // CSampleGrabberCB::SampleCB soll aufgerufen werden // Die Returnwerte müssen natürlich ausgewertet werden.Diese letzten Schritte erfolgen beim Erstellen des Preview-Graphen.
Wie Jochen Kalmbach bereits geschrieben hat, ist es möglich, dies auch in C umzusetzen. Du müsstest dir einmal die MS-Headerdateien mit den jeweiligen C-Interfaces anschauen.
Ich habe damit leider keinerlei Erfahrung.
-
Anon schrieb:
Das Problem ist, dass bei MSDN nirgendwo ein Beispiel dazu zu finden ist, wie man eine eigene Callback-Funktion definiert.
Weil es nur Callback-Interfaces gibt, keine einzeln stehenden Funktionen. Allerdings sind es keine dispinterfaces, was die Sache erheblich vereinfacht. ATL braucht man sich dann auch nicht unbedingt ans Bein zu binden.
Streamgrabber->SetCallback((ISampleGrabberCB *)grabSample, 1);Und eine Klasse kann ich nicht implementieren, da ich auf reines C angewiesen bin.
Dann kannst Du mit allen Samples nichts anfangen. In C sehen die Methoden Aufrufe nämlich ganz anders aus. Um bei Deinem Beispiel zu bleiben:
Streamgrabber->lpVtbl->SetCallback(Streamgrabber, ...);
-
Vielen dank für euere Beiträge, wie es scheint wird wohl kein Weg an C++ bzw einer Klasse vorbeiführen(hatte ich versucht zu vermeiden). Ich werde also mal probieren das ganze zum laufen zu bekommen.