Freigeben über


Gewusst wie: Erstellen und verwenden Sie Instanzen CComPtr und CComQIPtr

In der klassischen Windows-Programmierung werden Bibliotheken häufig als COM-Objekte (oder genauer gesagt als COM-Server) implementiert.Viele Windows-Komponenten als COM-Server implementiert sind, und viele Mitwirkende bieten Bibliotheken in diesem Formular.Informationen über die Grundlagen der COM finden Sie unter Component Object Model (COM).

Wenn Sie ein Component Object Model (COM)-Objekt instanziieren, speichern den Schnittstellenzeiger in ein smart COM-Schnittstellenzeiger, die die Verweiszählung durch Aufrufe ausführt AddRef und Release im Destruktor.Wenn Sie die Active Template Library (ATL) oder die Microsoft Foundation Class Library (MFC) verwenden, verwenden Sie die CComPtr intelligenten Zeiger.Wenn Sie die ATL oder MFC nicht verwenden, verwenden Sie _com_ptr_t.Denn es ist kein COM-äquivalent zu std::unique_ptr, diese intelligenten Zeigern für den Single-Besitzer und Multiple-Benutzer-Szenarien verwenden.Beide CComPtr und ComQIPtr Support Verschiebevorgänge Rvalue Verweise haben.

Beispiel

Im folgenden Beispiel wird veranschaulicht, wie mithilfe von CComPtr auf ein COM-Objekt instanziieren und Zeiger auf die Schnittstellen zu erhalten.Beachten Sie, dass die CComPtr::CoCreateInstance -Memberfunktion verwendet, das COM-Objekt anstelle der Win32-Funktion erstellen, die den gleichen 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.
}

CComPtrund seine verwandten sind Teil der ATL und in atlcomcli.h definiert sind._com_ptr_twird in comip.h deklariert.Der Compiler erstellt Spezialisierungen von _com_ptr_t Wenn Wrapperklassen für Typbibliotheken generiert.

ATL bietet auch CComQIPtr, die eine einfachere Syntax für die Abfrage ein COM-Objekt eine zusätzliche Schnittstelle abgerufen hat.Wir empfehlen jedoch, CComPtr weil es alles, die nicht CComQIPtr tun können und semantisch mehr im Einklang mit unformatierten COM-Schnittstellenzeigern.Wenn Sie verwenden ein CComPtr um eine Schnittstelle abzufragen, werden neue Schnittstellenzeiger in Out-Parameter.Wenn der Aufruf fehlschlägt, ist die typische COM-Muster ist ein HRESULT zurückgegeben.Mit CComQIPtr, der Rückgabewert ist der Zeiger selbst, und wenn der Aufruf fehlschlägt, kann nicht der internen HRESULT-Rückgabewert zugegriffen werden.Die folgenden beiden Zeilen anzeigen, 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*/ }

CComPtrStellt eine Spezialisierung für IDispatch, die Ihnen ermöglicht, Verweise auf COM-Automatisierungskomponenten speichern und Aufrufen von Methoden für die Schnittstelle mit späten Bindung bereit.CComDispatchDriverist eine Typedef für CComQIPtr<IDispatch, &IIDIDispatch>, das ist implizit in CComPtr<IDispatch>.Daher erscheint diese drei Namen im Code, es entspricht CComPtr<IDispatch>.Das folgende Beispiel veranschaulicht mithilfe ein Zeigers auf das Microsoft Word-Objektmodell erhalten eine CComPtr<IDispatch>.

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();
}

Siehe auch

Konzepte

Intelligente Zeiger modernes (C++)