Condividi tramite


com::ptr Class

Un wrapper per un oggetto COM che può essere utilizzato come membro di una classe CLR. Il wrapper consente anche di automatizzare la gestione della durata dell'oggetto COM, rilasciando tutti i riferimenti di proprietà nell'oggetto quando viene chiamato il distruttore. Analogo alla classe CComPtr.

Sintassi

template<class _interface_type>
ref class ptr;

Parametri

_interface_type
Interfaccia COM.

Osservazioni:

È possibile utilizzare com::ptr come variabile di funzione locale per semplificare le varie attività COM e automatizzare la gestione della durata.

Un com::ptr oggetto non può essere usato direttamente come parametro di funzione. Usare invece un operatore di riferimento Tracking o un operatore Handle to object (^).

Un com::ptr oggetto non può essere restituito direttamente da una funzione. Usare invece un handle.

Esempio

In questo esempio viene implementata una classe CLR che utilizza com::ptr per eseguire il wrapping del relativo oggetto membro privato IXMLDOMDocument. La chiamata dei metodi pubblici della classe determina le chiamate all'oggetto IXMLDOMDocument contenuto. Nell'esempio viene creata un'istanza di un documento XML, il documento viene completato con del codice XML semplice e vengono brevemente scorsi i nodi dell'albero del documento analizzato per stampare il contenuto XML nella console.

// comptr.cpp
// compile with: /clr /link msxml2.lib
#include <msxml2.h>
#include <msclr\com\ptr.h>

#import <msxml3.dll> raw_interfaces_only

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr;

// a ref class that uses a com::ptr to contain an
// IXMLDOMDocument object
ref class XmlDocument {
public:
   // construct the internal com::ptr with a null interface
   // and use CreateInstance to fill it
   XmlDocument(String^ progid) {
      m_ptrDoc.CreateInstance(progid);
   }

   void LoadXml(String^ xml) {
      pin_ptr<const wchar_t> pinnedXml = PtrToStringChars(xml);
      BSTR bstr = NULL;

      try {
         // load some XML into the document
         bstr = ::SysAllocString(pinnedXml);
         if (NULL == bstr) {
            throw gcnew OutOfMemoryException;
         }
         VARIANT_BOOL bIsSuccessful = false;
         // use operator -> to call IXMODOMDocument member function
         Marshal::ThrowExceptionForHR(m_ptrDoc->loadXML(bstr, &bIsSuccessful));
      }
      finally {
         ::SysFreeString(bstr);
      }
   }

   // simplified function to write just the first xml node to the console
   void WriteXml() {
      IXMLDOMNode* pNode = NULL;

      try {
         // the first child of the document is the first real xml node
         Marshal::ThrowExceptionForHR(m_ptrDoc->get_firstChild(&pNode));
         if (NULL != pNode) {
            WriteNode(pNode);
         }
      }
      finally {
         if (NULL != pNode) {
            pNode->Release();
         }
      }
   }

   // note that the destructor will call the com::ptr destructor
   // and automatically release the reference to the COM object

private:
   // simplified function that only writes the node
   void WriteNode(IXMLDOMNode* pNode) {
      BSTR bstr = NULL;

      try {
         // write out the name and text properties
         Marshal::ThrowExceptionForHR(pNode->get_nodeName(&bstr));
         String^ strName = gcnew String(bstr);
         Console::Write("<{0}>", strName);
         ::SysFreeString(bstr);
         bstr = NULL;

         Marshal::ThrowExceptionForHR(pNode->get_text(&bstr));
         Console::Write(gcnew String(bstr));
         ::SysFreeString(bstr);
         bstr = NULL;

         Console::WriteLine("</{0}>", strName);
      }
      finally {
         ::SysFreeString(bstr);
      }
   }

   com::ptr<IXMLDOMDocument> m_ptrDoc;
};

// use the ref class to handle an XML DOM Document object
int main() {
   try {
      // create the class from a progid string
      XmlDocument doc("Msxml2.DOMDocument.3.0");

      // stream some xml into the document
      doc.LoadXml("<word>persnickety</word>");

      // write the document to the console
      doc.WriteXml();
   }
   catch (Exception^ e) {
      Console::WriteLine(e);
   }
}
<word>persnickety</word>

Membri

Costruttori pubblici

Nome Descrizione
ptr::ptr Costruisce un oggetto com::ptr per eseguire il wrapping di un oggetto COM.
ptr::~ptr Decostruisce un oggetto com::ptr.

Metodi pubblici

Nome Descrizione
ptr::Attach Associa un oggetto COM a un oggetto com::ptr.
ptr::CreateInstance Crea un'istanza di un oggetto COM all'interno di un oggetto com::ptr.
ptr::Detach Rinuncia alla proprietà dell'oggetto COM, restituendo un puntatore all'oggetto .
ptr::GetInterface Crea un'istanza di un oggetto COM all'interno di un oggetto com::ptr.
ptr::QueryInterface Esegue una query sull'oggetto COM di proprietà per un'interfaccia e associa il risultato a un altro com::ptroggetto .
ptr::Release Rilascia tutti i riferimenti di proprietà sull'oggetto COM.

Operatori pubblici

Nome Descrizione
ptr::operator-> Operatore di accesso ai membri, utilizzato per chiamare metodi sull'oggetto COM di proprietà.
ptr::operator= Associa un oggetto COM a un oggetto com::ptr.
ptr::operator bool Operatore per l'uso com::ptr in un'espressione condizionale.
ptr::operator! Operatore per determinare se l'oggetto COM di proprietà non è valido.

Requisiti

File<di intestazione msclr\com\ptr.h>

Spazio dei nomi msclr::com

ptr::ptr

Restituisce un puntatore all'oggetto COM di proprietà.

ptr();
ptr(
   _interface_type * p
);

Parametri

P
Puntatore a interfaccia COM.

Osservazioni:

Il costruttore no-argument assegna nullptr all'handle dell'oggetto sottostante. Le chiamate future a convalideranno l'oggetto interno e avranno esito negativo in modo invisibile all'utente fino a com::ptr quando non viene creato o collegato un oggetto.

Il costruttore di un argomento aggiunge un riferimento all'oggetto COM, ma non rilascia il riferimento del chiamante, quindi il chiamante deve chiamare Release sull'oggetto COM per rinunciare al controllo. Quando il com::ptrdistruttore viene chiamato, il distruttore rilascia automaticamente i riferimenti sull'oggetto COM.

Il passaggio NULL a questo costruttore equivale a chiamare la versione senza argomenti.

Esempio

In questo esempio viene implementata una classe CLR che utilizza com::ptr per eseguire il wrapping del relativo oggetto membro privato IXMLDOMDocument. Illustra l'utilizzo di entrambe le versioni del costruttore.

// comptr_ptr.cpp
// compile with: /clr /link msxml2.lib
#include <msxml2.h>
#include <msclr\com\ptr.h>

#import <msxml3.dll> raw_interfaces_only

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr;

// a ref class that uses a com::ptr to contain an
// IXMLDOMDocument object
ref class XmlDocument {
public:
   // construct the internal com::ptr with a null interface
   // and use CreateInstance to fill it
   XmlDocument(String^ progid) {
      m_ptrDoc.CreateInstance(progid);
   }

   // construct the internal com::ptr with a COM object
   XmlDocument(IXMLDOMDocument* pDoc) : m_ptrDoc(pDoc) {}

   // note that the destructor will call the com::ptr destructor
   // and automatically release the reference to the COM object

private:
   com::ptr<IXMLDOMDocument> m_ptrDoc;
};

// use the ref class to handle an XML DOM Document object
int main() {
   IXMLDOMDocument* pDoc = NULL;

   try {
      // create an XML DOM document object
      Marshal::ThrowExceptionForHR(CoCreateInstance(CLSID_DOMDocument30, NULL,
         CLSCTX_ALL, IID_IXMLDOMDocument, (void**)&pDoc));
      // construct the ref class with the COM object
      XmlDocument doc1(pDoc);

      // or create the class from a progid string
      XmlDocument doc2("Msxml2.DOMDocument.3.0");
   }
   // doc1 and doc2 destructors are called when they go out of scope
   // and the internal com::ptr releases its reference to the COM object
   catch (Exception^ e) {
      Console::WriteLine(e);
   }
   finally {
      if (NULL != pDoc) {
         pDoc->Release();
      }
   }
}

ptr::~ptr

Decostruisce un oggetto com::ptr.

~ptr();

Osservazioni:

In caso di distruzione, rilascia com::ptr tutti i riferimenti di cui è proprietario all'oggetto COM. Supponendo che non ci siano altri riferimenti mantenuti all'oggetto COM, l'oggetto COM verrà eliminato e la relativa memoria liberata.

Esempio

In questo esempio viene implementata una classe CLR che utilizza com::ptr per eseguire il wrapping del relativo oggetto membro privato IXMLDOMDocument. main Nella funzione, i distruttori dei due XmlDocument oggetti verranno chiamati quando escono dall'ambito del try blocco, causando la chiamata del distruttore sottostantecom::ptr, rilasciando tutti i riferimenti di proprietà all'oggetto COM.

// comptr_dtor.cpp
// compile with: /clr /link msxml2.lib
#include <msxml2.h>
#include <msclr\com\ptr.h>

#import <msxml3.dll> raw_interfaces_only

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr;

// a ref class that uses a com::ptr to contain an
// IXMLDOMDocument object
ref class XmlDocument {
public:
   // construct the internal com::ptr with a null interface
   // and use CreateInstance to fill it
   XmlDocument(String^ progid) {
      m_ptrDoc.CreateInstance(progid);
   }

   // construct the internal com::ptr with a COM object
   XmlDocument(IXMLDOMDocument* pDoc) : m_ptrDoc(pDoc) {}

   // note that the destructor will call the com::ptr destructor
   // and automatically release the reference to the COM object

private:
   com::ptr<IXMLDOMDocument> m_ptrDoc;
};

// use the ref class to handle an XML DOM Document object
int main() {
   IXMLDOMDocument* pDoc = NULL;

   try {
      // create an XML DOM document object
      Marshal::ThrowExceptionForHR(CoCreateInstance(CLSID_DOMDocument30, NULL,
         CLSCTX_ALL, IID_IXMLDOMDocument, (void**)&pDoc));
      // construct the ref class with the COM object
      XmlDocument doc1(pDoc);

      // or create the class from a progid string
      XmlDocument doc2("Msxml2.DOMDocument.3.0");
   }
   // doc1 and doc2 destructors are called when they go out of scope
   // and the internal com::ptr releases its reference to the COM object
   catch (Exception^ e) {
      Console::WriteLine(e);
   }
   finally {
      if (NULL != pDoc) {
         pDoc->Release();
      }
   }
}

ptr::Attach

Associa un oggetto COM a un oggetto com::ptr.

void Attach(
   _interface_type * _right
);

Parametri

_A destra
Puntatore all'interfaccia COM da collegare.

Eccezioni

Se l'oggetto com::ptr è già proprietario di un riferimento a un oggetto COM, Attach genera InvalidOperationException.

Osservazioni:

Una chiamata a fa riferimento all'oggetto Attach COM, ma non rilascia il riferimento del chiamante.

Il passaggio NULL a Attach non comporta l'esecuzione di alcuna azione.

Esempio

In questo esempio viene implementata una classe CLR che utilizza com::ptr per eseguire il wrapping del relativo oggetto membro privato IXMLDOMDocument. La ReplaceDocument funzione membro chiama Release prima su qualsiasi oggetto di proprietà precedente e quindi chiama Attach per allegare un nuovo oggetto documento.

// comptr_attach.cpp
// compile with: /clr /link msxml2.lib
#include <msxml2.h>
#include <msclr\com\ptr.h>

#import <msxml3.dll> raw_interfaces_only

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr;

// a ref class that uses a com::ptr to contain an
// IXMLDOMDocument object
ref class XmlDocument {
public:
   // construct the internal com::ptr with a null interface
   // and use CreateInstance to fill it
   XmlDocument(String^ progid) {
      m_ptrDoc.CreateInstance(progid);
   }

   // replace currently held COM object with another one
   void ReplaceDocument(IXMLDOMDocument* pDoc) {
      // release current document object
      m_ptrDoc.Release();
      // attach the new document object
      m_ptrDoc.Attach(pDoc);
   }

   // note that the destructor will call the com::ptr destructor
   // and automatically release the reference to the COM object

private:
   com::ptr<IXMLDOMDocument> m_ptrDoc;
};

// unmanaged function that creates a raw XML DOM Document object
IXMLDOMDocument* CreateDocument() {
   IXMLDOMDocument* pDoc = NULL;
   Marshal::ThrowExceptionForHR(CoCreateInstance(CLSID_DOMDocument30, NULL,
      CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&pDoc));
   return pDoc;
}

// use the ref class to handle an XML DOM Document object
int main() {
   IXMLDOMDocument* pDoc = NULL;

   try {
      // create the class from a progid string
      XmlDocument doc("Msxml2.DOMDocument.3.0");

      // get another document object from unmanaged function and
      // store it in place of the one held by our ref class
      pDoc = CreateDocument();
      doc.ReplaceDocument(pDoc);
      // no further need for raw object reference
      pDoc->Release();
      pDoc = NULL;
   }
   catch (Exception^ e) {
      Console::WriteLine(e);
   }
   finally {
      if (NULL != pDoc) {
         pDoc->Release();
      }
   }
}

ptr::CreateInstance

Crea un'istanza di un oggetto COM all'interno di un oggetto com::ptr.

void CreateInstance(
   System::String ^ progid,
   LPUNKNOWN pouter,
   DWORD cls_context
);
void CreateInstance(
   System::String ^ progid,
   LPUNKNOWN pouter
);
void CreateInstance(
   System::String ^ progid
);
void CreateInstance(
   const wchar_t * progid,
   LPUNKNOWN pouter,
   DWORD cls_context
);
void CreateInstance(
   const wchar_t * progid,
   LPUNKNOWN pouter
);
void CreateInstance(
   const wchar_t * progid
);
void CreateInstance(
   REFCLSID rclsid,
   LPUNKNOWN pouter,
   DWORD cls_context
);
void CreateInstance(
   REFCLSID rclsid,
   LPUNKNOWN pouter
);
void CreateInstance(
   REFCLSID rclsid
);

Parametri

progid
Stringa ProgID.

pouter
Puntatore all'interfaccia IUnknown dell'oggetto aggregato (controllo IUnknown). Se pouter non viene specificato, NULL viene usato .

cls_context
Contesto in cui verrà eseguito il codice che gestisce l'oggetto appena creato. I valori vengono ricavati dall'enumerazione CLSCTX . Se cls_context non viene specificato, viene usato il valore CLSCTX_ALL.

rclsid
CLSID associato ai dati e al codice che verranno usati per creare l'oggetto .

Eccezioni

Se l'oggetto com::ptr è già proprietario di un riferimento a un oggetto COM, CreateInstance genera InvalidOperationException.

Questa funzione chiama CoCreateInstance e usa ThrowExceptionForHR per convertire qualsiasi errore HRESULT in un'eccezione appropriata.

Osservazioni:

CreateInstance usa CoCreateInstance per creare una nuova istanza dell'oggetto specificato, identificata da un ProgID o da un CLSID. Fa com::ptr riferimento all'oggetto appena creato e rilascia automaticamente tutti i riferimenti di proprietà in caso di distruzione.

Esempio

In questo esempio viene implementata una classe CLR che utilizza com::ptr per eseguire il wrapping del relativo oggetto membro privato IXMLDOMDocument. I costruttori di classi usano due forme diverse di CreateInstance per creare l'oggetto documento da un ProgID o da un CLSID più un CLSCTX.

// comptr_createinstance.cpp
// compile with: /clr /link msxml2.lib
#include <msxml2.h>
#include <msclr\com\ptr.h>

#import <msxml3.dll> raw_interfaces_only

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr;

// a ref class that uses a com::ptr to contain an
// IXMLDOMDocument object
ref class XmlDocument {
public:
   // construct the internal com::ptr with a null interface
   // and use CreateInstance to fill it
   XmlDocument(String^ progid) {
      m_ptrDoc.CreateInstance(progid);
   }
   XmlDocument(REFCLSID clsid, DWORD clsctx) {
      m_ptrDoc.CreateInstance(clsid, NULL, clsctx);
   }

   // note that the destructor will call the com::ptr destructor
   // and automatically release the reference to the COM object

private:
   com::ptr<IXMLDOMDocument> m_ptrDoc;
};

// use the ref class to handle an XML DOM Document object
int main() {
   try {
      // create the class from a progid string
      XmlDocument doc1("Msxml2.DOMDocument.3.0");

      // or from a clsid with specific CLSCTX
      XmlDocument doc2(CLSID_DOMDocument30, CLSCTX_INPROC_SERVER);
   }
   catch (Exception^ e) {
      Console::WriteLine(e);
   }
}

ptr::Detach

Rinuncia alla proprietà dell'oggetto COM, restituendo un puntatore all'oggetto .

_interface_type * Detach();

Valore restituito

Puntatore all'oggetto COM.

Se non è di proprietà alcun oggetto, viene restituito NULL.

Eccezioni

Internamente, QueryInterface viene chiamato sull'oggetto COM di proprietà e qualsiasi errore HRESULT viene convertito in un'eccezione da ThrowExceptionForHR.

Osservazioni:

Detach aggiunge innanzitutto un riferimento all'oggetto COM per conto del chiamante e quindi rilascia tutti i riferimenti di proprietà dell'oggetto com::ptr. Il chiamante deve infine rilasciare l'oggetto restituito per distruggerlo.

Esempio

In questo esempio viene implementata una classe CLR che utilizza com::ptr per eseguire il wrapping del relativo oggetto membro privato IXMLDOMDocument. La DetachDocument funzione membro chiama Detach per rinunciare alla proprietà dell'oggetto COM e restituire un puntatore al chiamante.

// comptr_detach.cpp
// compile with: /clr /link msxml2.lib
#include <msxml2.h>
#include <msclr\com\ptr.h>

#import <msxml3.dll> raw_interfaces_only

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr;

// a ref class that uses a com::ptr to contain an
// IXMLDOMDocument object
ref class XmlDocument {
public:
   // construct the internal com::ptr with a null interface
   // and use CreateInstance to fill it
   XmlDocument(String^ progid) {
      m_ptrDoc.CreateInstance(progid);
   }

   // detach the COM object and return it
   // this releases the internal reference to the object
   IXMLDOMDocument* DetachDocument() {
      return m_ptrDoc.Detach();
   }

   // note that the destructor will call the com::ptr destructor
   // and automatically release the reference to the COM object

private:
   com::ptr<IXMLDOMDocument> m_ptrDoc;
};

// unmanaged function that loads XML into a raw XML DOM Document object
HRESULT LoadXml(IXMLDOMDocument* pDoc, BSTR bstrXml) {
   HRESULT hr = S_OK;
   VARIANT_BOOL bSuccess;
   hr = pDoc->loadXML(bstrXml, &bSuccess);
   if (S_OK == hr && !bSuccess) {
      hr = E_FAIL;
   }
   return hr;
}

// use the ref class to handle an XML DOM Document object
int main() {
   IXMLDOMDocument* pDoc = NULL;
   BSTR bstrXml = NULL;

   try {
      // create the class from a progid string
      XmlDocument doc("Msxml2.DOMDocument.3.0");

      bstrXml = ::SysAllocString(L"<word>persnickety</word>");
      if (NULL == bstrXml) {
         throw gcnew OutOfMemoryException("bstrXml");
      }
      // detach the document object from the ref class
      pDoc = doc.DetachDocument();
      // use unmanaged function and raw object to load xml
      Marshal::ThrowExceptionForHR(LoadXml(pDoc, bstrXml));
      // release document object as the ref class no longer owns it
      pDoc->Release();
      pDoc = NULL;
   }
   catch (Exception^ e) {
      Console::WriteLine(e);
   }
   finally {
      if (NULL != pDoc) {
         pDoc->Release();
      }

   }
}

ptr::GetInterface

Restituisce un puntatore all'oggetto COM di proprietà.

_interface_type * GetInterface();

Valore restituito

Puntatore all'oggetto COM di proprietà.

Eccezioni

Internamente, QueryInterface viene chiamato sull'oggetto COM di proprietà e qualsiasi errore HRESULT viene convertito in un'eccezione da ThrowExceptionForHR.

Osservazioni:

Aggiunge com::ptr un riferimento all'oggetto COM per conto del chiamante e mantiene il proprio riferimento sull'oggetto COM. Il chiamante deve infine rilasciare il riferimento sull'oggetto restituito o non verrà mai eliminato definitivamente.

Esempio

In questo esempio viene implementata una classe CLR che utilizza com::ptr per eseguire il wrapping del relativo oggetto membro privato IXMLDOMDocument. La GetDocument funzione membro utilizza GetInterface per restituire un puntatore all'oggetto COM.

// comptr_getinterface.cpp
// compile with: /clr /link msxml2.lib
#include <msxml2.h>
#include <msclr\com\ptr.h>

#import <msxml3.dll> raw_interfaces_only

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr;

// a ref class that uses a com::ptr to contain an
// IXMLDOMDocument object
ref class XmlDocument {
public:
   // construct the internal com::ptr with a null interface
   // and use CreateInstance to fill it
   XmlDocument(String^ progid) {
      m_ptrDoc.CreateInstance(progid);
   }

   // add a reference to and return the COM object
   // but keep an internal reference to the object
   IXMLDOMDocument* GetDocument() {
      return m_ptrDoc.GetInterface();
   }

   // simplified function that only writes the first node
   void WriteDocument() {
      IXMLDOMNode* pNode = NULL;
      BSTR bstr = NULL;

      try {
         // use operator -> to call XML Doc member
         Marshal::ThrowExceptionForHR(m_ptrDoc->get_firstChild(&pNode));
         if (NULL != pNode) {
            // write out the xml
            Marshal::ThrowExceptionForHR(pNode->get_nodeName(&bstr));
            String^ strName = gcnew String(bstr);
            Console::Write("<{0}>", strName);
            ::SysFreeString(bstr);
            bstr = NULL;

            Marshal::ThrowExceptionForHR(pNode->get_text(&bstr));
            Console::Write(gcnew String(bstr));
            ::SysFreeString(bstr);
            bstr = NULL;

            Console::WriteLine("</{0}>", strName);
         }
      }
      finally {
         if (NULL != pNode) {
            pNode->Release();
         }
         ::SysFreeString(bstr);
      }
   }

   // note that the destructor will call the com::ptr destructor
   // and automatically release the reference to the COM object

private:
   com::ptr<IXMLDOMDocument> m_ptrDoc;
};

// unmanaged function that loads XML into a raw XML DOM Document object
HRESULT LoadXml(IXMLDOMDocument* pDoc, BSTR bstrXml) {
   HRESULT hr = S_OK;
   VARIANT_BOOL bSuccess;
   hr = pDoc->loadXML(bstrXml, &bSuccess);
   if (S_OK == hr && !bSuccess) {
      hr = E_FAIL;
   }
   return hr;
}

// use the ref class to handle an XML DOM Document object
int main() {
   IXMLDOMDocument* pDoc = NULL;
   BSTR bstrXml = NULL;

   try {
      // create the class from a progid string
      XmlDocument doc("Msxml2.DOMDocument.3.0");

      bstrXml = ::SysAllocString(L"<word>persnickety</word>");
      if (NULL == bstrXml) {
         throw gcnew OutOfMemoryException("bstrXml");
      }
      // detach the document object from the ref class
      pDoc = doc.GetDocument();
      // use unmanaged function and raw object to load xml
      Marshal::ThrowExceptionForHR(LoadXml(pDoc, bstrXml));
      // release reference to document object (but ref class still references it)
      pDoc->Release();
      pDoc = NULL;

      // call another function on the ref class
      doc.WriteDocument();
   }
   catch (Exception^ e) {
      Console::WriteLine(e);
   }
   finally {
      if (NULL != pDoc) {
         pDoc->Release();
      }

   }
}
<word>persnickety</word>

ptr::QueryInterface

Esegue una query sull'oggetto COM di proprietà per un'interfaccia e associa il risultato a un altro com::ptroggetto .

template<class _other_type>
void QueryInterface(
   ptr<_other_type> % other
);

Parametri

other
Oggetto com::ptr che otterrà l'interfaccia.

Eccezioni

Internamente, QueryInterface viene chiamato sull'oggetto COM di proprietà e qualsiasi errore HRESULT viene convertito in un'eccezione da ThrowExceptionForHR.

Osservazioni:

Utilizzare questo metodo per creare un wrapper COM per un'interfaccia diversa dell'oggetto COM di proprietà del wrapper corrente. Questo metodo chiama QueryInterface tramite l'oggetto COM di proprietà per richiedere un puntatore a un'interfaccia specifica dell'oggetto COM e associa il puntatore dell'interfaccia restituito all'oggetto passato com::ptr.

Esempio

In questo esempio viene implementata una classe CLR che utilizza com::ptr per eseguire il wrapping del relativo oggetto membro privato IXMLDOMDocument. La WriteTopLevelNode funzione membro usa QueryInterface per riempire un oggetto locale com::ptr con un IXMLDOMNode e quindi passa l'oggetto com::ptr (mediante il rilevamento del riferimento) a una funzione membro privata che scrive il nome e le proprietà di testo del nodo nella console.

// comptr_queryinterface.cpp
// compile with: /clr /link msxml2.lib
#include <msxml2.h>
#include <msclr\com\ptr.h>

#import <msxml3.dll> raw_interfaces_only

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr;

// a ref class that uses a com::ptr to contain an
// IXMLDOMDocument object
ref class XmlDocument {
public:
   // construct the internal com::ptr with a null interface
   // and use CreateInstance to fill it
   XmlDocument(String^ progid) {
      m_ptrDoc.CreateInstance(progid);
   }

   void LoadXml(String^ xml) {
      pin_ptr<const wchar_t> pinnedXml = PtrToStringChars(xml);
      BSTR bstr = NULL;

      try {
         // load some XML into our document
         bstr = ::SysAllocString(pinnedXml);
         if (NULL == bstr) {
            throw gcnew OutOfMemoryException;
         }
         VARIANT_BOOL bIsSuccessful = false;
         // use operator -> to call IXMODOMDocument member function
         Marshal::ThrowExceptionForHR(m_ptrDoc->loadXML(bstr, &bIsSuccessful));
      }
      finally {
         ::SysFreeString(bstr);
      }
   }

   // write the top level node to the console
   void WriteTopLevelNode() {
      com::ptr<IXMLDOMNode> ptrNode;

      // query for the top level node interface
      m_ptrDoc.QueryInterface(ptrNode);
      WriteNode(ptrNode);
   }

   // note that the destructor will call the com::ptr destructor
   // and automatically release the reference to the COM object

private:
   // simplified function that only writes the node
   void WriteNode(com::ptr<IXMLDOMNode> % node) {
      BSTR bstr = NULL;

      try {
         // write out the name and text properties
         Marshal::ThrowExceptionForHR(node->get_nodeName(&bstr));
         String^ strName = gcnew String(bstr);
         Console::Write("<{0}>", strName);
         ::SysFreeString(bstr);
         bstr = NULL;

         Marshal::ThrowExceptionForHR(node->get_text(&bstr));
         Console::Write(gcnew String(bstr));
         ::SysFreeString(bstr);
         bstr = NULL;

         Console::WriteLine("</{0}>", strName);
      }
      finally {
         ::SysFreeString(bstr);
      }
   }

   com::ptr<IXMLDOMDocument> m_ptrDoc;
};

// use the ref class to handle an XML DOM Document object
int main() {
   try {
      // create the class from a progid string
      XmlDocument doc("Msxml2.DOMDocument.3.0");

      // stream some xml into the document
      doc.LoadXml("<word>persnickety</word>");

      // write the document to the console
      doc.WriteTopLevelNode();
   }
   catch (Exception^ e) {
      Console::WriteLine(e);
   }
}
<#document>persnickety</#document>

ptr::Release

Rilascia tutti i riferimenti di proprietà sull'oggetto COM.

void Release();

Osservazioni:

La chiamata a questa funzione rilascia tutti i riferimenti di proprietà sull'oggetto COM e imposta l'handle interno sull'oggetto COM su nullptr. Se non esistono altri riferimenti sull'oggetto COM, verrà eliminato definitivamente.

Esempio

In questo esempio viene implementata una classe CLR che utilizza com::ptr per eseguire il wrapping del relativo oggetto membro privato IXMLDOMDocument. La ReplaceDocument funzione membro usa Release per rilasciare qualsiasi oggetto documento precedente prima di allegare il nuovo documento.

// comptr_release.cpp
// compile with: /clr /link msxml2.lib
#include <msxml2.h>
#include <msclr\com\ptr.h>

#import <msxml3.dll> raw_interfaces_only

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr;

// a ref class that uses a com::ptr to contain an
// IXMLDOMDocument object
ref class XmlDocument {
public:
   // construct the internal com::ptr with a null interface
   // and use CreateInstance to fill it
   XmlDocument(String^ progid) {
      m_ptrDoc.CreateInstance(progid);
   }

   // replace currently held COM object with another one
   void ReplaceDocument(IXMLDOMDocument* pDoc) {
      // release current document object
      m_ptrDoc.Release();
      // attach the new document object
      m_ptrDoc.Attach(pDoc);
   }

   // note that the destructor will call the com::ptr destructor
   // and automatically release the reference to the COM object

private:
   com::ptr<IXMLDOMDocument> m_ptrDoc;
};

// unmanaged function that creates a raw XML DOM Document object
IXMLDOMDocument* CreateDocument() {
   IXMLDOMDocument* pDoc = NULL;
   Marshal::ThrowExceptionForHR(CoCreateInstance(CLSID_DOMDocument30, NULL,
      CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&pDoc));
   return pDoc;
}

// use the ref class to handle an XML DOM Document object
int main() {
   IXMLDOMDocument* pDoc = NULL;

   try {
      // create the class from a progid string
      XmlDocument doc("Msxml2.DOMDocument.3.0");

      // get another document object from unmanaged function and
      // store it in place of the one held by our ref class
      pDoc = CreateDocument();
      doc.ReplaceDocument(pDoc);
      // no further need for raw object reference
      pDoc->Release();
      pDoc = NULL;
   }
   catch (Exception^ e) {
      Console::WriteLine(e);
   }
   finally {
      if (NULL != pDoc) {
         pDoc->Release();
      }
   }
}

ptr::operator->

Operatore di accesso ai membri, utilizzato per chiamare metodi sull'oggetto COM di proprietà.

_detail::smart_com_ptr<_interface_type> operator->();

Valore restituito

Oggetto smart_com_ptr all'oggetto COM.

Eccezioni

Internamente, QueryInterface viene chiamato sull'oggetto COM di proprietà e qualsiasi errore HRESULT viene convertito in un'eccezione da ThrowExceptionForHR.

Osservazioni:

Questo operatore consente di chiamare i metodi dell'oggetto COM di proprietà. Restituisce un oggetto temporaneo smart_com_ptr che gestisce automaticamente il proprio AddRef oggetto e Release.

Esempio

In questo esempio viene implementata una classe CLR che utilizza com::ptr per eseguire il wrapping del relativo oggetto membro privato IXMLDOMDocument. La WriteDocument funzione usa operator-> per chiamare il get_firstChild membro dell'oggetto documento.

// comptr_op_member.cpp
// compile with: /clr /link msxml2.lib
#include <msxml2.h>
#include <msclr\com\ptr.h>

#import <msxml3.dll> raw_interfaces_only

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr;

// a ref class that uses a com::ptr to contain an
// IXMLDOMDocument object
ref class XmlDocument {
public:
   // construct the internal com::ptr with a null interface
   // and use CreateInstance to fill it
   XmlDocument(String^ progid) {
      m_ptrDoc.CreateInstance(progid);
   }

   // add a reference to and return the COM object
   // but keep an internal reference to the object
   IXMLDOMDocument* GetDocument() {
      return m_ptrDoc.GetInterface();
   }

   // simplified function that only writes the first node
   void WriteDocument() {
      IXMLDOMNode* pNode = NULL;
      BSTR bstr = NULL;

      try {
         // use operator -> to call XML Doc member
         Marshal::ThrowExceptionForHR(m_ptrDoc->get_firstChild(&pNode));
         if (NULL != pNode) {
            // write out the xml
            Marshal::ThrowExceptionForHR(pNode->get_nodeName(&bstr));
            String^ strName = gcnew String(bstr);
            Console::Write("<{0}>", strName);
            ::SysFreeString(bstr);
            bstr = NULL;

            Marshal::ThrowExceptionForHR(pNode->get_text(&bstr));
            Console::Write(gcnew String(bstr));
            ::SysFreeString(bstr);
            bstr = NULL;

            Console::WriteLine("</{0}>", strName);
         }
      }
      finally {
         if (NULL != pNode) {
            pNode->Release();
         }
         ::SysFreeString(bstr);
      }
   }

   // note that the destructor will call the com::ptr destructor
   // and automatically release the reference to the COM object

private:
   com::ptr<IXMLDOMDocument> m_ptrDoc;
};

// unmanaged function that loads XML into a raw XML DOM Document object
HRESULT LoadXml(IXMLDOMDocument* pDoc, BSTR bstrXml) {
   HRESULT hr = S_OK;
   VARIANT_BOOL bSuccess;
   hr = pDoc->loadXML(bstrXml, &bSuccess);
   if (S_OK == hr && !bSuccess) {
      hr = E_FAIL;
   }
   return hr;
}

// use the ref class to handle an XML DOM Document object
int main() {
   IXMLDOMDocument* pDoc = NULL;
   BSTR bstrXml = NULL;

   try {
      // create the class from a progid string
      XmlDocument doc("Msxml2.DOMDocument.3.0");

      bstrXml = ::SysAllocString(L"<word>persnickety</word>");
      if (NULL == bstrXml) {
         throw gcnew OutOfMemoryException("bstrXml");
      }
      // detach the document object from the ref class
      pDoc = doc.GetDocument();
      // use unmanaged function and raw object to load xml
      Marshal::ThrowExceptionForHR(LoadXml(pDoc, bstrXml));
      // release reference to document object (but ref class still references it)
      pDoc->Release();
      pDoc = NULL;

      // call another function on the ref class
      doc.WriteDocument();
   }
   catch (Exception^ e) {
      Console::WriteLine(e);
   }
   finally {
      if (NULL != pDoc) {
         pDoc->Release();
      }

   }
}
<word>persnickety</word>

ptr::operator=

Associa un oggetto COM a un oggetto com::ptr.

ptr<_interface_type> % operator=(
   _interface_type * _right
);

Parametri

_A destra
Puntatore all'interfaccia COM da collegare.

Valore restituito

Riferimento di rilevamento in com::ptr.

Eccezioni

Se l'oggetto com::ptr è già proprietario di un riferimento a un oggetto COM, operator= genera InvalidOperationException.

Osservazioni:

L'assegnazione di un oggetto COM a un com::ptr oggetto FA riferimento all'oggetto COM, ma non rilascia il riferimento del chiamante.

Questo operatore ha lo stesso effetto di Attach.

Esempio

In questo esempio viene implementata una classe CLR che utilizza com::ptr per eseguire il wrapping del relativo oggetto membro privato IXMLDOMDocument. La ReplaceDocument funzione membro chiama Release prima su qualsiasi oggetto di proprietà precedente e quindi usa operator= per allegare un nuovo oggetto documento.

// comptr_op_assign.cpp
// compile with: /clr /link msxml2.lib
#include <msxml2.h>
#include <msclr\com\ptr.h>

#import <msxml3.dll> raw_interfaces_only

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr;

// a ref class that uses a com::ptr to contain an
// IXMLDOMDocument object
ref class XmlDocument {
public:
   // construct the internal com::ptr with a null interface
   // and use CreateInstance to fill it
   XmlDocument(String^ progid) {
      m_ptrDoc.CreateInstance(progid);
   }

   // replace currently held COM object with another one
   void ReplaceDocument(IXMLDOMDocument* pDoc) {
      // release current document object
      m_ptrDoc.Release();
      // attach the new document object
      m_ptrDoc = pDoc;
   }

   // note that the destructor will call the com::ptr destructor
   // and automatically release the reference to the COM object

private:
   com::ptr<IXMLDOMDocument> m_ptrDoc;
};

// unmanaged function that creates a raw XML DOM Document object
IXMLDOMDocument* CreateDocument() {
   IXMLDOMDocument* pDoc = NULL;
   Marshal::ThrowExceptionForHR(CoCreateInstance(CLSID_DOMDocument30, NULL,
      CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&pDoc));
   return pDoc;
}

// use the ref class to handle an XML DOM Document object
int main() {
   IXMLDOMDocument* pDoc = NULL;

   try {
      // create the class from a progid string
      XmlDocument doc("Msxml2.DOMDocument.3.0");

      // get another document object from unmanaged function and
      // store it in place of the one held by the ref class
      pDoc = CreateDocument();
      doc.ReplaceDocument(pDoc);
      // no further need for raw object reference
      pDoc->Release();
      pDoc = NULL;
   }
   catch (Exception^ e) {
      Console::WriteLine(e);
   }
   finally {
      if (NULL != pDoc) {
         pDoc->Release();
      }
   }
}

ptr::operator bool

Operatore per l'uso com::ptr in un'espressione condizionale.

operator bool();

Valore restituito

true se l'oggetto COM di proprietà è valido; false altrimenti.

Osservazioni:

L'oggetto COM di proprietà è valido se non nullptrè .

Questo operatore converte in _detail_class::_safe_bool un tipo più sicuro di bool perché non può essere convertito in un tipo integrale.

Esempio

In questo esempio viene implementata una classe CLR che utilizza com::ptr per eseguire il wrapping del relativo oggetto membro privato IXMLDOMDocument. La CreateInstance funzione membro usa operator bool dopo la creazione del nuovo oggetto documento per determinare se è valida e scrive nella console se è.

// comptr_op_bool.cpp
// compile with: /clr /link msxml2.lib
#include <msxml2.h>
#include <msclr\com\ptr.h>

#import <msxml3.dll> raw_interfaces_only

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr;

// a ref class that uses a com::ptr to contain an
// IXMLDOMDocument object
ref class XmlDocument {
public:
   void CreateInstance(String^ progid) {
      if (!m_ptrDoc) {
         m_ptrDoc.CreateInstance(progid);
         if (m_ptrDoc) { // uses operator bool
            Console::WriteLine("DOM Document created.");
         }
      }
   }

   // note that the destructor will call the com::ptr destructor
   // and automatically release the reference to the COM object

private:
   com::ptr<IXMLDOMDocument> m_ptrDoc;
};

// use the ref class to handle an XML DOM Document object
int main() {
   try {
      XmlDocument doc;
      // create the instance from a progid string
      doc.CreateInstance("Msxml2.DOMDocument.3.0");
   }
   catch (Exception^ e) {
      Console::WriteLine(e);
   }
}
DOM Document created.

ptr::operator!

Operatore per determinare se l'oggetto COM di proprietà non è valido.

bool operator!();

Valore restituito

true se l'oggetto COM di proprietà non è valido; false altrimenti.

Osservazioni:

L'oggetto COM di proprietà è valido se non nullptrè .

Esempio

In questo esempio viene implementata una classe CLR che utilizza com::ptr per eseguire il wrapping del relativo oggetto membro privato IXMLDOMDocument. La CreateInstance funzione membro usa operator! per determinare se un oggetto documento è già di proprietà e crea una nuova istanza solo se l'oggetto non è valido.

// comptr_op_not.cpp
// compile with: /clr /link msxml2.lib
#include <msxml2.h>
#include <msclr\com\ptr.h>

#import <msxml3.dll> raw_interfaces_only

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr;

// a ref class that uses a com::ptr to contain an
// IXMLDOMDocument object
ref class XmlDocument {
public:
   void CreateInstance(String^ progid) {
      if (!m_ptrDoc) {
         m_ptrDoc.CreateInstance(progid);
         if (m_ptrDoc) {
            Console::WriteLine("DOM Document created.");
         }
      }
   }

   // note that the destructor will call the com::ptr destructor
   // and automatically release the reference to the COM object

private:
   com::ptr<IXMLDOMDocument> m_ptrDoc;
};

// use the ref class to handle an XML DOM Document object
int main() {
   try {
      XmlDocument doc;
      // create the instance from a progid string
      doc.CreateInstance("Msxml2.DOMDocument.3.0");
   }
   catch (Exception^ e) {
      Console::WriteLine(e);
   }
}
DOM Document created.