Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In Windows - klassisch Programmierung, werden Bibliotheken häufig als COM-Objekte implementiert (oder genau, COM-Server als). Viele Komponenten des Windows-Betriebssystems werden als COM-Server implementiert, und viele Mitwirkende stellen Bibliotheken in dieser Form. Informationen über die Grundlagen von COM, finden Sie unter Component Object Model (COM).
Wenn Sie ein (Component Object Model (COM)- Objekt instanziieren, speichern Sie den von Schnittstellenzeigern in einem COM-intelligentenZeiger, der die Verweiszählung ausgeführt, indem Aufrufe von AddRef und Release im Destruktor verwendet. Wenn Sie Active Template Library (ATL) oder der Microsoft Foundation Class-Bibliothek " (MFC-Bibliothek) verwenden, verwenden Sie den intelligenten Zeiger CComPtr. Wenn Sie nicht ATL oder MFC verwenden, verwenden Sie _com_ptr_t. Da keine COM-Entsprechung zu std::unique_ptr vorhanden sind, verwenden Sie diese intelligenten Zeiger für EinzelBesitzers- und MehrfachverbindungsstelleBesitzersszenarien. CComPtr und ComQIPtr unterstützen Verschiebungsvorgänge, die rvalue-Verweise haben.
Beispiel
Das folgende Beispiel zeigt, wie CComPtr verwendet, um ein COM-Objekt und Zeiger abzurufen den Schnittstellen zu instanziieren. Beachten Sie, dass die CComPtr::CoCreateInstance-Memberfunktion verwendet wird, um das COM-Objekt erstellen, statt der Win32-Funktion, die denselben Namen hat.
void CComPtrDemo()
{
HRESULT hr = CoInitialize(NULL);
// Declare the smart pointer.
CComPtr<IGraphBuilder> pGraph;
// Use its member function CoCreateInstance to
// create the COM object and obtain the IGraphBuilder pointer.
hr = pGraph.CoCreateInstance(CLSID_FilterGraph);
if(FAILED(hr)){ /*... handle hr error*/ }
// Use the overloaded -> operator to call the interface methods.
hr = pGraph->RenderFile(L"C:\\Users\\Public\\Music\\Sample Music\\Sleep Away.mp3", NULL);
if(FAILED(hr)){ /*... handle hr error*/ }
// Declare a second smart pointer and use it to
// obtain another interface from the object.
CComPtr<IMediaControl> pControl;
hr = pGraph->QueryInterface(IID_PPV_ARGS(&pControl));
if(FAILED(hr)){ /*... handle hr error*/ }
// Obtain a third interface.
CComPtr<IMediaEvent> pEvent;
hr = pGraph->QueryInterface(IID_PPV_ARGS(&pEvent));
if(FAILED(hr)){ /*... handle hr error*/ }
// Use the second interface.
hr = pControl->Run();
if(FAILED(hr)){ /*... handle hr error*/ }
// Use the third interface.
long evCode = 0;
pEvent->WaitForCompletion(INFINITE, &evCode);
CoUninitialize();
// Let the smart pointers do all reference counting.
}
CComPtr und die relativen sind Teil des ATL und werden in atlcomcli.h definiert. _com_ptr_t wird in comip.h deklariert. Der Compiler erstellt Spezialisierungen von _com_ptr_t, wenn er Wrapperklassen für Typbibliotheken generiert.
ATL stellt auch ein CComQIPtr, das eine einfachere Syntax zum Abfragen eines COM-Objekts, um eine zusätzliche Schnittstelle abgerufen hat. jedoch abgeraten CComPtr, da er aktiv wird, das CComQIPtr ausführen kann und Semantik mit unformatierten COM-Schnittstellenzeigern inern synchronisiert ist. Wenn Sie CComPtr verwenden, um für eine Schnittstelle abzufragen, wird der neue Schnittstellenzeiger in einen Out-Parameter eingefügt. Wenn der Aufruf fehlschlägt, wird ein HRESULT zurückgegeben, das das typische COM-Muster ist. Mit CComQIPtr ist der Rückgabewert der Zeiger selbst, und wenn der Aufruf fehlschlägt, kann auf den internen HRESULT-Rückgabewert nicht zugegriffen werden. Die folgenden beiden Zeilen zeigen, wie die Fehlerbehandlungsmechanismen in CComPtr und CComQIPtr unterscheiden.
// CComPtr with error handling:
CComPtr<IMediaControl> pControl;
hr = pGraph->QueryInterface(IID_PPV_ARGS(&pControl));
if(FAILED(hr)){ /*... handle hr error*/ }
// CComQIPtr with error handling
CComQIPtr<IMediaEvent> pEvent = pControl;
if(!pEvent){ /*... handle NULL pointer error*/ }
// Use the second interface.
hr = pControl->Run();
if(FAILED(hr)){ /*... handle hr error*/ }
CComPtr stellt eine Spezialisierung für IDispatch bereit, die es ermöglicht, Zeiger auf den COM-Automatisierungskomponenten zu speichern und die Methoden für die Schnittstelle aufzurufen, indem er als späte Bindung verwendet. CComDispatchDriver ist eine Typdefinition für CComQIPtr<IDispatch, &IIDIDispatch>, die CComPtr<IDispatch> implizit konvertiert werden kann. Wenn alle drei Namen im Code angezeigt wird, ist es für CComPtr<IDispatch>. Das folgende Beispiel zeigt, wie ein Zeiger dem Microsoft Word-Objektmodell erhält, indem es CComPtr<IDispatch> verwendet.
void COMAutomationSmartPointerDemo()
{
CComPtr<IDispatch> pWord;
CComQIPtr<IDispatch, &IID_IDispatch> pqi = pWord;
CComDispatchDriver pDriver = pqi;
HRESULT hr;
_variant_t pOutVal;
CoInitialize(NULL);
hr = pWord.CoCreateInstance(L"Word.Application", NULL, CLSCTX_LOCAL_SERVER);
if(FAILED(hr)){ /*... handle hr error*/ }
// Make Word visible.
hr = pWord.PutPropertyByName(_bstr_t("Visible"), &_variant_t(1));
if(FAILED(hr)){ /*... handle hr error*/ }
// Get the Documents collection and store it in new CComPtr
hr = pWord.GetPropertyByName(_bstr_t("Documents"), &pOutVal);
if(FAILED(hr)){ /*... handle hr error*/ }
CComPtr<IDispatch> pDocuments = pOutVal.pdispVal;
// Use Documents to open a document
hr = pDocuments.Invoke1 (_bstr_t("Open"), &_variant_t("c:\\users\\public\\documents\\sometext.txt"),&pOutVal);
if(FAILED(hr)){ /*... handle hr error*/ }
CoUninitialize();
}