COM-Objekt mit benutzerdefiniertem Interface



  • Hallo,

    ich weiß nicht, ob ich hier im WinAPI-Forum richtig bin, wenn nicht, verschiebt mein Posting bitte entsprechend.

    Ich habe ein Problem mit dem Erstellen einer COM-Komponente, die ein benutzerdefiniertes (also von mir festgelegtes) Interface haben soll. Ich habe schon lange daran herumprobiert, kann den Fehler aber nicht finden 😞

    Konkret handelt es sich bei der Komponente um einen DirectShow-Filter. Für den Filter selber habe ich vorerst ein beim DirectX-SDK mitgeliefertes Beispiel ("PushSource") genommen.

    Nun zu meinem Problem: Um den Filter konfigurieren und bestimmte Daten übertragen zu können, möchte ich der COM-Komponente ein neues Interface hinzufügen. Ich habe ich das Interface wie folgt definiert und das Programm wird auch problemlos kompiliert.

    import "oaidl.idl";
    import "ocidl.idl";
    
    [
        uuid( ... ),
        version(1.0),
        helpstring("Img2VidFilter")
    ]
    library Img2VidFilter
    {
         importlib("stdole32.tlb");
         importlib("stdole2.tlb");
         [
              object,
              uuid( ... ),
              helpstring("IImg2VidFilter Interface"),
              pointer_default(unique)
         ]
         interface IImg2VidFilter : IUnknown
         {
              HRESULT Test(void);
         };
    };
    

    Die Klassendefinition sieht wie folgt aus:

    class CImg2VidFilter : public CSource, IImg2VidFilter
    {
    public:
    	DECLARE_IUNKNOWN;
    
    	STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv)
    	{
    		if (riid == IID_IImg2VidFilter)
    			return GetInterface(reinterpret_cast<IImg2VidFilter*>(this), ppv);
    		else
    			return CSource::NonDelegatingQueryInterface(riid, ppv);
    	}
    
    	static CUnknown * WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr);
    
    	// IImg2VidFilter-Methoden
    	STDMETHODIMP Test(void); //HRESULT Test(void);
    
    private:
    	CImg2VidFilter(IUnknown *pUnk, HRESULT *phr);
    	~CImg2VidFilter();
    
    	COutputPin *m_pPin;
    };
    

    Die Implementierung der Methode:

    STDMETHODIMP CImg2VidFilter::Test(void)
    {
    	return 0;
    }
    

    Zum Schluss noch das Testprogramm:

    ...
    #include "customInterfaces_h.h"    //vom Compiler mithilfe der idl-Datei erstellt
    DEFINE_GUID(CLSID_Img2VidFilter, ... );
    ...
    IBaseFilter *pFilter = 0;
    IImg2VidFilter *pCustomInterface = 0;
    HRESULT hRes;
    
    hRes = CoCreateInstance(CLSID_Img2VidFilter, 0, CLSCTX_INPROC_SERVER,
    IID_IBaseFilter, reinterpret_cast<LPVOID*>(&pFilter));
    if (FAILED(hRes))
       throw "error";
    
    hRes = pFilter->QueryInterface(IID_IImg2VidFilter,
    (void**)&pCustomInterface);
    if (FAILED(hRes))
       throw "error";
    
    if (pCustomInterface == 0)
     throw "error";
    pCustomInterface->Test();   //hier stürzt das Programm ab (siehe unten)
    pCustomInterface->Release();
    
    pFilter->Release();
    ...
    

    Leider stürzt das Testprogramm immer mit einer Fehlermeldung ab:

    Unbehandelte Ausnahme bei 0x01674acb (img2vidFilter.dll) in DShow-1.exe: 0xC0000005: Zugriffsverletzung-Schreibposition 0x0169721c.
    

    Was mache ich falsch? Muss ich vielleicht noch irgendwelche Einstellungen in der IDE ändern (ich benutze VC++ .net 2003 Standard) oder weitere Dateien einbinden?

    Sven



  • Wo genau kommt denn der Fehler (Debugger)?



  • Ich bin jetzt nur schnell drübergeflogen, aber:

    Sven25 schrieb:

    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv)
    	{
    		if (riid == IID_IImg2VidFilter)
    			return GetInterface(reinterpret_cast<IImg2VidFilter*>(this), ppv);
    		else
    			return CSource::NonDelegatingQueryInterface(riid, ppv);
    	}
    

    Sollte das nicht static_cast anstelle von reinterpret_cast heissen?



  • flenders schrieb:

    Wo genau kommt denn der Fehler (Debugger)?

    Sven25 schrieb:

    pCustomInterface->Test();   //hier stürzt das Programm ab (siehe unten)
    pCustomInterface->Release();
    


  • Hallo,

    wie gesagt, er tritt in der Zeile

    pCustomInterface->Test();
    

    im Testprogramm auf. Kommentiere ich sie aus, stürzt das Programm nicht mehr ab.

    Der Debugger spring, wenn ich bei der Fehlermeldung auf "Unterbrechen" drücke, in den Quelltext des Filters (also der COM-Komponente). Er geht dann automatisch zur Zeile, die den Destruktor enthält. An dem kann es aber kaum liegen, da der Absturz auch auftritt, wenn der Destruktor keine Befehle enthält.

    Sven

    (Edit:) -King- war schneller, ich wurde beim Tippen der Antwort kurz unterbrochen.



  • Irgendwie habe ich aber trotzdem noch den Eindruck, daß Du meinen ersten Beitrag nicht gelesen hast. Also nochmal: static_cast!



  • Hallo,

    -King- schrieb:

    Irgendwie habe ich aber trotzdem noch den Eindruck, daß Du meinen ersten Beitrag nicht gelesen hast. Also nochmal: static_cast!

    Doch, -King-, ich habe ihn gelesen. Aber ich habe deinen Tipp bis gerade noch ausprobiert und war nun dabei, die Antwort zu schreiben.

    -King- schrieb:

    Sven25 schrieb:

    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv)
    	{
    		if (riid == IID_IImg2VidFilter)
    			return GetInterface(reinterpret_cast<IImg2VidFilter*>(this), ppv);
    		else
    			return CSource::NonDelegatingQueryInterface(riid, ppv);
    	}
    

    Sollte das nicht static_cast anstelle von reinterpret_cast heissen?

    Super, vielen Dank! Jetzt funktioniert es! 🙂

    Sven


Anmelden zum Antworten