2009-07-01 2 views
1

ich folgendes CComPtr Objekt und Methode in meiner Klasse definiert haben:Compilation Fehler durch falsche Verwendung von CComPtr Objekte

private: 

    CComPtr<IRawPdu>& getRawPdu(); 
    // Returns the RawPdu interface pointer from the mRawPdu data member. 
    // mRawPdu is initialized, if necessary. 

    CComPtr<IRawPdu> mRawPdu; 
    // Initialized to 0 in the ctor. Uses lazy evaluation via getRawPdu(). 

Im Konstruktor meiner Klasse, ich mRawPdu auf 0 über die initialisor Liste initialisieren. Die Methode getRawPdu() hat die Lazy-Auswertung verwendet, wenn mRawPdu noch nicht initialisiert wurde.

Wenn Sie den Code kompilieren, erhalte ich folgende Fehler:

Compiling... 
topport.cpp 
C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\atlcomcli.h(295) : error C2664: 'ATL::AtlComPtrAssign' : cannot convert parameter 2 from 'const ATL::CComPtr<T>' to 'IUnknown *' 
     with 
     [ 
      T=IRawPdu 
     ] 
     No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 
     C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\atlcomcli.h(292) : while compiling class template member function 'IRawPdu *ATL::CComPtr<T>::operator =(const ATL::CComPtr<T> &) throw()' 
     with 
     [ 
      T=IRawPdu 
     ] 
     sessionutilities.h(186) : see reference to class template instantiation 'ATL::CComPtr<T>' being compiled 
     with 
     [ 
      T=IRawPdu 
     ] 
topglobals.cpp 
C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\atlcomcli.h(295) : error C2664: 'ATL::AtlComPtrAssign' : cannot convert parameter 2 from 'const ATL::CComPtr<T>' to 'IUnknown *' 
     with 
     [ 
      T=IRawPdu 
     ] 
     No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 
     C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\atlcomcli.h(292) : while compiling class template member function 'IRawPdu *ATL::CComPtr<T>::operator =(const ATL::CComPtr<T> &) throw()' 
     with 
     [ 
      T=IRawPdu 
     ] 
     sessionutilities.h(186) : see reference to class template instantiation 'ATL::CComPtr<T>' being compiled 
     with 
     [ 
      T=IRawPdu 
     ] 

Irgendwelche Vorschläge, was dieses verursachen könnte?

Antwort

2

Basierend auf dem vom Compiler angegebenen Fehler scheint es, dass er keine Konvertierung zwischen IRawPdu und IUnknown ableiten kann.

Erbt es tatsächlich von IUnknown? Wenn ja, dann ist es möglicherweise ein Problem mit der Bestellung von Bestellungen. Kannst du mehr Einblick in die Hierarchie von IRawPdu geben

+0

IRawPdu erbt von IDispatch, die von IUnknown wiederum erbt

IRawPdu* getRawPdu() { return mRawPdu; } // Does not add to the reference count HRESULT get_RawPdu(IRawPdu** ppPdu) // Returns RawPdu, but add ref's it. { return mRawPdu.CopyTo(ppPdu); } CComPtr<IRawPdu> mRawPdu; // Initialized to 0 in the ctor. Uses lazy evaluation via getRawPdu(). 

Also, wenn es Zeit, es zu benutzen kommt. Das Seltsame ist, dass das gut funktionierte, aber dann habe ich das mRawPdu-Objekt in eine andere Klasse verschoben, und nur JETZT ist es mit diesen Fehlern versagt. Vielleicht ist es ein Problem mit der Bestellung von Includes, aber ich bin nicht sicher, wie ich es isolieren kann. – LeopardSkinPillBoxHat

+0

Ich habe es gerade herausgefunden - Ihr "include ordering issue" Kommentar war der Schlüssel. Das Problem war, dass viele andere .cpp-Dateien meine Header-Datei mit der CComPtr-Definition enthielten, aber die IRawPdu-Deklaration wurde nur in die .cpp-Datei aufgenommen, in der ich sie verwendete. Ich habe die MIDL-generierte Header-Datei verschoben, die die Schnittstelle in den vorkompilierten Header stdafx.h definiert, und es schien das Problem zu beheben. Danke für die Vorschläge! – LeopardSkinPillBoxHat

0

Pass nicht CComPtr <> ist um, da es keine Notwendigkeit gibt, nur den Zeiger auf die Schnittstelle zurück. Zum Beispiel:

IRawPdu* pTempRawPdu = class->getRawPdu(); 
    // use pTempRawPdu in a temporary manner (since it's not add reffed) 

Aber besser wäre:

CComPtr<IRawPdu> spRawPdu = class->getRawPdu(); 
    // the ctor of the local CComPtr<> calls AddRef() (and automagically Release's when done)