Entwickler-Ecke

Windows API - Windows COM Problem mit CoCreateInstance


Tobi482 - Sa 30.01.10 17:01
Titel: Windows COM Problem mit CoCreateInstance
Hi Leute,

ich hoffe, dass die Frage unter WindowsAPI richtig angesiedelt ist, da es sich eigentlich um ein COM Problem handelt.

Ich programmiere gerade etwas mit DirectShow herum. Zum Testen und besserem Debuggen programmiere ich den ersten Code in C++, da es hierfür akutellere Header und meist mehr Dokumentation gibt. Laufen die Subroutinen, exportiere ich sie in Delphi oder benutze DLLs. Ich bin kein Experte was COM_Programmierung angeht, jedoch bin ich in der Lage die fundamentalen Funktionen zu benutzen.

Folgende Zeile lässt sich in C++ ohne Probleme compilieren, jedoch löst sie in Delphi7Pro einen Fehler aus.


Quelltext
1:
2:
3:
4:
5:
        // {B86F6BEE-E7C0-4d03-8D52-5B4430CF6C88}
        DEFINE_GUID(CLSID_FFDSHOWAUDIORAW, 0xb86f6bee, 0xe7c0, 0x4d03, 0x8d, 0x52, 0x5b, 0x44, 0x30, 0xcf, 0x6c, 0x88)
        ...
  hr = CoCreateInstance(CLSID_FFDSHOWAUDIORAW, NULL, CLSCTX_ALL, IID_IBaseFilter, (void**)&pAudioProc[id]);
  if(FAILED(hr)) return -5;



Delphi-Quelltext
1:
2:
3:
4:
        IID_IBaseFilter: TGUID = '{56A86895-0AD4-11CE-B03A-0020AF0BA770}';
        ...
        Result := CoCreateInstance(CLSID_FFDSHOWAUDIORAW, nil, CLSCTX_ALL, IID_IBaseFilter, pAudioF[id]);
        if Failed(Result) then exit;


DelphiFehlerCode: -2147221164 = REGDB_E_CLASSNOTREG(0x80040154L)

REGDB_E_CLASSNOTREG
A specified class is not registered in the registration database. Also can indicate that the type of server you requested in the CLSCTX enumeration is not registered or the values for the server types in the registry are corrupt.


Mit folgendem Parameter wird eine Object gefunden


Delphi-Quelltext
1:
2:
3:
4:
        IID_IBaseFilter: TGUID = '{56A86895-0AD4-11CE-B03A-0020AF0BA770}';
        ...
  Result := CoCreateInstance(CLSID_FFDSHOWAUDIORAW, nil, CLSCTX_INPROC_SERVER, IID_IBaseFilter, pAudioF[id]);
  if Failed(Result) then exit;


DelphiFehlerCode: -2147467262 = E_NOINTERFACE(0x80004002L)

E_NOINTERFACE
The specified class does not implement the requested interface, or the controlling IUnknown does not expose the requested interface.

Wenn nun das gewünschte Object gefunden wurde wieso verweigert es unter Delphi das entsprechende Interface und unter C++ gibt es dabei keine Probleme?

Bin für jeden Tipp dankebar!

Mit freundlichen Grüßen
Tobi


JDF - So 31.01.10 19:28

Hi Tobi,

versuch doch mal ob Du das IUnknown-Interface als erstes Interface vom Objekt zurückbekommst,
damit Du den Objekt-Create als Fehlerursache komplett ausschließen kannst.

Folgendes Ergebnis wäre interessant:


Delphi-Quelltext
1:
Result := CoCreateInstance(CLSID_FFDSHOWAUDIORAW, nil, CLSCTX_INPROC_SERVER, IUnknown, pAudioF[id]);                    

Wenn das läuft, kannst Du mit IUnknown.QueryInterface(IID_IBaseFilter, out) an dein Interface gelangen.


E_NOINTERFACE: dein IID_IBaseFilter-Interface ist vom Objekt nicht abrufbar.
Kann auftreten, egal ob eine Objekt-Instanz existiert oder nicht.
(Die Factory kann schon spinnen)


Gruß
Jürgen


Tobi482 - Mo 01.02.10 12:21

Hi,

danke für deine Antwort. Du hattest recht. Die folgende Zeile gibt keinen FehlerCode zurück

Delphi-Quelltext
1:
2:
     Result := CoCreateInstance(CLSID_FFDSHOWAUDIORAW, nil, CLSCTX_INPROC_SERVER, IID_IUnknown, pAudioFInk[id]);
     if Failed(Result) then exit;

jedoch kann kein IBaseFilter-Interface referenziert werden

Delphi-Quelltext
1:
2:
     Result := pAudioFInk[id].QueryInterface(IID_IBaseFilter, pAudioF[id]);
     if Failed(Result) then exit;


Es scheint, als ob dieses Object das IBaseFilter-Interface nicht unterstützt.

Dies ist der Code, den ich in Delphi übersetzen wollte.

Quelltext
1:
2:
3:
4:
5:
  //create ffdshow audio processor filter
  hr = CoCreateInstance(CLSID_FFDSHOWAUDIORAW, NULL, CLSCTX_ALL, IID_IBaseFilter, (void**)&pAudioProc[id]);
  if(FAILED(hr)) return -5;
  hr = pAudioProc[id]->QueryInterface(IID_IffdshowBaseA, (void**)&pAudioProcBase[id]);
        if(FAILED(hr)) return -6;

Ich brauche das IBaseFilter-Interface um den Filter mit pGraph.Add zum FilterGraph hinzufügen und später das IffdshowBaseA-Interface um den Filter zur Laufzeit zu konfigurieren.

Folgende Zeile gibt seltsamerweise ebenfalls keinen Fehler zurück. Das Object konnte also erfolgreich referenziert werden.


Delphi-Quelltext
1:
2:
    Result := CoCreateInstance(CLSID_FFDSHOWAUDIORAW, nil, CLSCTX_INPROC_SERVER, IID_IffdshowBaseA, pAudioFffdshow[id]);
    if Failed(Result) then exit;


Ich bin nun in der Lage den Filter zu konfigurieren, kann ihn jedoch nicht zum FilterGraph hinzufügen um ihn zu benutzen.

Mit freundlichen Grüßen
Tobi