Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
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.