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::ptr oggetto . |
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::ptr
distruttore 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::ptr
oggetto .
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.