com::ptr, classe
Wrapper pour un objet COM qui peut être utilisé en tant que membre d’une classe CLR. Le wrapper automatise également la gestion de la durée de vie de l’objet COM, libérant toutes les références détenues sur l’objet lorsque son destructeur est appelé. Analogue à la classe CComPtr.
Syntaxe
template<class _interface_type>
ref class ptr;
Paramètres
_interface_type
Interface COM.
Notes
Un com::ptr
peut également être utilisé comme variable de fonction locale pour simplifier différentes tâches COM et automatiser la gestion de la durée de vie.
Impossible com::ptr
d’utiliser un paramètre de fonction directement ; utilisez plutôt un opérateur de référence tracking ou un handle pour l’opérateur objet (^).
Impossible com::ptr
de retourner directement à partir d’une fonction ; utilisez plutôt un handle.
Exemple
Cet exemple implémente une classe CLR qui utilise un com::ptr
wrapper son objet membre IXMLDOMDocument
privé. L’appel des méthodes publiques de la classe entraîne des appels à l’objet contenu IXMLDOMDocument
. L’exemple crée une instance d’un document XML, le remplit avec un code XML simple et effectue une procédure simplifiée des nœuds de l’arborescence de documents analysées pour imprimer le code XML dans la 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>
Membres
Constructeurs publics
Nom | Description |
---|---|
ptr::ptr | Construit un com::ptr objet COM pour encapsuler un objet COM. |
ptr::~ptr | Déstructe un com::ptr . |
Méthodes publiques
Nom | Description |
---|---|
ptr::Attach | Attache un objet COM à un com::ptr . |
ptr::CreateInstance | Crée une instance d’un objet COM dans un com::ptr . |
ptr::Detach | Abandonne la propriété de l’objet COM, retournant un pointeur vers l’objet. |
ptr::GetInterface | Crée une instance d’un objet COM dans un com::ptr . |
ptr::QueryInterface | Interroge l’objet COM appartenant à une interface et attache le résultat à un autre com::ptr . |
ptr::Release | Libère toutes les références détenues sur l’objet COM. |
Opérateurs publics
Nom | Description |
---|---|
ptr::operator-> |
Opérateur d’accès aux membres, utilisé pour appeler des méthodes sur l’objet COM appartenant. |
ptr::operator= | Attache un objet COM à un com::ptr . |
ptr::operator bool | Opérateur à utiliser com::ptr dans une expression conditionnelle. |
ptr::operator! | Opérateur pour déterminer si l’objet COM appartenant n’est pas valide. |
Spécifications
Fichier d’en-tête<msclr\com\ptr.h>
Espace de noms msclr ::com
ptr::ptr
Retourne un pointeur vers l’objet COM appartenant.
ptr();
ptr(
_interface_type * p
);
Paramètres
P
Pointeur d'interface COM.
Notes
Le constructeur sans argument affecte nullptr
au handle d’objet sous-jacent. Les appels ultérieurs à l’objet com::ptr
interne valident l’objet interne et échouent silencieusement jusqu’à ce qu’un objet soit créé ou attaché.
Le constructeur d’un argument ajoute une référence à l’objet COM, mais ne libère pas la référence de l’appelant, de sorte que l’appelant doit appeler Release
l’objet COM pour abandonner réellement le contrôle. Lorsque le com::ptr
destructeur de l’objet COM est appelé, il libère automatiquement ses références sur l’objet COM.
Le passage NULL
à ce constructeur est identique à l’appel de la version sans argument.
Exemple
Cet exemple implémente une classe CLR qui utilise un com::ptr
wrapper son objet membre IXMLDOMDocument
privé. Il illustre l’utilisation des deux versions du constructeur.
// 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
Déstructe un com::ptr
.
~ptr();
Notes
Lors de la destruction, la com::ptr
version libère toutes les références qu’elle possède à son objet COM. En supposant qu’il n’existe aucune autre référence à l’objet COM, l’objet COM est supprimé et sa mémoire libérée.
Exemple
Cet exemple implémente une classe CLR qui utilise un com::ptr
wrapper son objet membre IXMLDOMDocument
privé. Dans la main
fonction, les destructeurs des deux XmlDocument
objets sont appelés lorsqu’ils sortent de l’étendue du try
bloc, ce qui entraîne l’appel du destructeur sous-jacent com::ptr
, en libérant toutes les références détenues à l’objet 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
Attache un objet COM à un com::ptr
.
void Attach(
_interface_type * _right
);
Paramètres
_Droite
Pointeur de l’interface COM à attacher.
Exceptions
Si la com::ptr
propriété possède déjà une référence à un objet COM, Attach
lève InvalidOperationException.
Notes
Un appel pour référencer Attach
l’objet COM, mais ne libère pas la référence de l’appelant.
Passer NULL
à des Attach
résultats sans aucune action en cours.
Exemple
Cet exemple implémente une classe CLR qui utilise un com::ptr
wrapper son objet membre IXMLDOMDocument
privé. La ReplaceDocument
fonction membre appelle Release
d’abord n’importe quel objet précédemment détenu, puis appelle Attach
à attacher un nouvel objet de document.
// 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
Crée une instance d’un objet COM dans un 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
);
Paramètres
progid
Chaîne ProgID
.
pouter
Pointeur vers l’interface IUnknown de l’objet d’agrégation (IUnknown de contrôle). Si pouter
ce n’est pas spécifié, NULL
il est utilisé.
cls_context
Contexte dans lequel le code qui gère l’objet nouvellement créé s’exécute. Les valeurs sont extraites de l’énumération CLSCTX
. Si cls_context
ce n’est pas spécifié, la valeur CLSCTX_ALL est utilisée.
rclsid
CLSID
associé aux données et au code qui seront utilisés pour créer l’objet.
Exceptions
Si la com::ptr
propriété possède déjà une référence à un objet COM, CreateInstance
lève InvalidOperationException.
Cette fonction appelle CoCreateInstance
et utilise ThrowExceptionForHR pour convertir toute erreur HRESULT
en exception appropriée.
Notes
CreateInstance
permet CoCreateInstance
de créer une instance de l’objet spécifié, identifiée à partir d’un ProgID ou d’un CLSID. Les com::ptr
références à l’objet nouvellement créé et libèrent automatiquement toutes les références détenues lors de la destruction.
Exemple
Cet exemple implémente une classe CLR qui utilise un com::ptr
wrapper son objet membre IXMLDOMDocument
privé. Les constructeurs de classe utilisent deux formes différentes de CreateInstance
création de l’objet document à partir d’un ProgID ou d’un CLSID et d’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
Abandonne la propriété de l’objet COM, retournant un pointeur vers l’objet.
_interface_type * Detach();
Valeur retournée
Pointeur vers l’objet COM.
Si aucun objet n’est détenu, NULL est retourné.
Exceptions
En interne, QueryInterface
elle est appelée sur l’objet COM appartenant et toute erreur HRESULT
est convertie en exception par ThrowExceptionForHR.
Notes
Detach
ajoute d’abord une référence à l’objet COM pour le compte de l’appelant, puis libère toutes les références détenues par le com::ptr
. L’appelant doit finalement libérer l’objet retourné pour le détruire.
Exemple
Cet exemple implémente une classe CLR qui utilise un com::ptr
wrapper son objet membre IXMLDOMDocument
privé. La DetachDocument
fonction membre appelle Detach
pour abandonner la propriété de l’objet COM et retourner un pointeur vers l’appelant.
// 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
Retourne un pointeur vers l’objet COM appartenant.
_interface_type * GetInterface();
Valeur retournée
Pointeur vers l’objet COM appartenant.
Exceptions
En interne, QueryInterface
elle est appelée sur l’objet COM appartenant et toute erreur HRESULT
est convertie en exception par ThrowExceptionForHR.
Notes
Ajoute com::ptr
une référence à l’objet COM au nom de l’appelant et conserve également sa propre référence sur l’objet COM. L’appelant doit finalement libérer la référence sur l’objet retourné ou ne sera jamais détruit.
Exemple
Cet exemple implémente une classe CLR qui utilise un com::ptr
wrapper son objet membre IXMLDOMDocument
privé. La GetDocument
fonction membre utilise GetInterface
pour renvoyer un pointeur vers l’objet 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
Interroge l’objet COM appartenant à une interface et attache le résultat à un autre com::ptr
.
template<class _other_type>
void QueryInterface(
ptr<_other_type> % other
);
Paramètres
other
Qui com::ptr
obtiendra l’interface.
Exceptions
En interne, QueryInterface
elle est appelée sur l’objet COM appartenant et toute erreur HRESULT
est convertie en exception par ThrowExceptionForHR.
Notes
Utilisez cette méthode pour créer un wrapper COM pour une autre interface de l’objet COM appartenant au wrapper actuel. Cette méthode appelle QueryInterface
par le biais de l’objet COM détenu pour demander un pointeur vers une interface spécifique de l’objet COM et attache le pointeur d’interface retourné au passage com::ptr
.
Exemple
Cet exemple implémente une classe CLR qui utilise un com::ptr
wrapper son objet membre IXMLDOMDocument
privé. La WriteTopLevelNode
fonction membre utilise QueryInterface
pour remplir un local com::ptr
avec un IXMLDOMNode
puis passer ( com::ptr
par référence de suivi) à une fonction membre privée qui écrit le nom et les propriétés de texte du nœud dans la 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
Libère toutes les références détenues sur l’objet COM.
void Release();
Notes
L’appel de cette fonction libère toutes les références détenues sur l’objet COM et définit le handle interne sur l’objet nullptr
COM sur . Si aucune autre référence n’existe sur l’objet COM, elle sera détruite.
Exemple
Cet exemple implémente une classe CLR qui utilise un com::ptr
wrapper son objet membre IXMLDOMDocument
privé. La ReplaceDocument
fonction membre utilise Release
pour libérer tout objet de document antérieur avant d’attacher le nouveau document.
// 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->
Opérateur d’accès aux membres, utilisé pour appeler des méthodes sur l’objet COM appartenant.
_detail::smart_com_ptr<_interface_type> operator->();
Valeur retournée
À smart_com_ptr
l’objet COM.
Exceptions
En interne, QueryInterface
elle est appelée sur l’objet COM appartenant et toute erreur HRESULT
est convertie en exception par ThrowExceptionForHR.
Notes
Cet opérateur vous permet d’appeler des méthodes de l’objet COM appartenant. Il retourne un temporaire smart_com_ptr
qui gère automatiquement ses propres et Release
AddRef
.
Exemple
Cet exemple implémente une classe CLR qui utilise un com::ptr
wrapper son objet membre IXMLDOMDocument
privé. La WriteDocument
fonction utilise operator->
pour appeler le get_firstChild
membre de l’objet document.
// 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=
Attache un objet COM à un com::ptr
.
ptr<_interface_type> % operator=(
_interface_type * _right
);
Paramètres
_Droite
Pointeur de l’interface COM à attacher.
Valeur retournée
Référence de suivi sur le com::ptr
.
Exceptions
Si la com::ptr
propriété possède déjà une référence à un objet COM, operator=
lève InvalidOperationException.
Notes
L’affectation d’un objet COM à une com::ptr
référence à l’objet COM, mais ne libère pas la référence de l’appelant.
Cet opérateur a le même effet que Attach
.
Exemple
Cet exemple implémente une classe CLR qui utilise un com::ptr
wrapper son objet membre IXMLDOMDocument
privé. La ReplaceDocument
fonction membre appelle Release
d’abord n’importe quel objet précédemment détenu, puis utilise operator=
pour attacher un nouvel objet de document.
// 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
Opérateur à utiliser com::ptr
dans une expression conditionnelle.
operator bool();
Valeur retournée
true
si l’objet COM appartenant est valide ; false
autrement.
Notes
L’objet COM appartenant est valide si ce n’est pas le cas nullptr
.
Cet opérateur se convertit en _detail_class::_safe_bool
valeur plus sûre que bool
parce qu’il ne peut pas être converti en type intégral.
Exemple
Cet exemple implémente une classe CLR qui utilise un com::ptr
wrapper son objet membre IXMLDOMDocument
privé. La CreateInstance
fonction membre utilise operator bool
après avoir créé le nouvel objet de document pour déterminer s’il est valide et écrit dans la console s’il s’agit.
// 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!
Opérateur pour déterminer si l’objet COM appartenant n’est pas valide.
bool operator!();
Valeur retournée
true
si l’objet COM détenu n’est pas valide ; false
autrement.
Notes
L’objet COM appartenant est valide si ce n’est pas le cas nullptr
.
Exemple
Cet exemple implémente une classe CLR qui utilise un com::ptr
wrapper son objet membre IXMLDOMDocument
privé. La CreateInstance
fonction membre utilise operator!
pour déterminer si un objet document est déjà détenu et crée uniquement une instance si l’objet n’est pas valide.
// 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.