Skip to content

Latest commit

 

History

History
1417 lines (1105 loc) · 39.6 KB

com-ptr-class.md

File metadata and controls

1417 lines (1105 loc) · 39.6 KB
descriptiontitlems.datems.topicf1_keywordshelpviewer_keywordsms.assetid
Learn more about: com::ptr Class
com::ptr Class
01/16/2019
reference
msclr::com::ptr::ptr
msclr::com::ptr::Attach
msclr::com::ptr::CreateInstance
msclr::com::ptr::Detach
msclr::com::ptr::GetInterface
msclr::com::ptr::QueryInterface
msclr::com::ptr::Release
msclr::com::ptr::operator=
msclr::com::ptr::operator->
msclr::com::ptr::operator!
msclr::ptr class
0144d0e4-919c-45f9-a3f8-fbc9edba32bf

com::ptr Class

A wrapper for a COM object that can be used as a member of a CLR class. The wrapper also automates lifetime management of the COM object, releasing all owned references on the object when its destructor is called. Analogous to CComPtr class.

Syntax

template<class _interface_type> ref class ptr; 

Parameters

_interface_type
COM interface.

Remarks

A com::ptr can also be used as a local function variable to simplify various COM tasks and to automate lifetime management.

A com::ptr can't be used directly as a function parameter; use a Tracking reference operator or a Handle to object operator (^) instead.

A com::ptr can't be directly returned from a function; use a handle instead.

Example

This example implements a CLR class that uses a com::ptr to wrap its private member IXMLDOMDocument object. Calling the public methods of the class results in calls to the contained IXMLDOMDocument object. The sample creates an instance of an XML document, fills it with some simple XML, and does a simplified walk of the nodes in the parsed document tree to print the XML to the console.

// comptr.cpp// compile with: /clr /link msxml2.lib #include<msxml2.h> #include<msclr\com\ptr.h> #import<msxml3.dll> raw_interfaces_only usingnamespaceSystem;usingnamespaceSystem::Runtime::InteropServices;usingnamespacemsclr;// a ref class that uses a com::ptr to contain an// IXMLDOMDocument object ref classXmlDocument { public:// construct the internal com::ptr with a null interface// and use CreateInstance to fill itXmlDocument(String^ progid) { m_ptrDoc.CreateInstance(progid); } voidLoadXml(String^ xml) { pin_ptr<constwchar_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 functionMarshal::ThrowExceptionForHR(m_ptrDoc->loadXML(bstr, &bIsSuccessful)); } finally { ::SysFreeString(bstr); } } // simplified function to write just the first xml node to the consolevoidWriteXml() { IXMLDOMNode* pNode = NULL; try { // the first child of the document is the first real xml nodeMarshal::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 objectprivate:// simplified function that only writes the nodevoidWriteNode(IXMLDOMNode* pNode) { BSTR bstr = NULL; try { // write out the name and text propertiesMarshal::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 objectintmain() { 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> 

Members

Public constructors

NameDescription
ptr::ptrConstructs a com::ptr to wrap a COM object.
ptr::~ptrDestructs a com::ptr.

Public methods

NameDescription
ptr::AttachAttaches a COM object to a com::ptr.
ptr::CreateInstanceCreates an instance of a COM object within a com::ptr.
ptr::DetachGives up ownership of the COM object, returning a pointer to the object.
ptr::GetInterfaceCreates an instance of a COM object within a com::ptr.
ptr::QueryInterfaceQueries the owned COM object for an interface and attaches the result to another com::ptr.
ptr::ReleaseReleases all owned references on the COM object.

Public operators

NameDescription
ptr::operator->Member access operator, used to call methods on the owned COM object.
ptr::operator=Attaches a COM object to a com::ptr.
ptr::operator boolOperator for using com::ptr in a conditional expression.
ptr::operator!Operator to determine if the owned COM object is invalid.

Requirements

Header file <msclr\com\ptr.h>

Namespace msclr::com

ptr::ptr

Returns a pointer to the owned COM object.

ptr(); ptr( _interface_type * p );

Parameters

P
A COM interface pointer.

Remarks

The no-argument constructor assigns nullptr to the underlying object handle. Future calls to the com::ptr will validate the internal object and silently fail until an object is created or attached.

The one-argument constructor adds a reference to the COM object but doesn't release the caller's reference, so the caller must call Release on the COM object to truly give up control. When the com::ptr's destructor is called it will automatically release its references on the COM object.

Passing NULL to this constructor is the same as calling the no-argument version.

Example

This example implements a CLR class that uses a com::ptr to wrap its private member IXMLDOMDocument object. It demonstrates usage of both versions of the constructor.

// comptr_ptr.cpp// compile with: /clr /link msxml2.lib #include<msxml2.h> #include<msclr\com\ptr.h> #import<msxml3.dll> raw_interfaces_only usingnamespaceSystem;usingnamespaceSystem::Runtime::InteropServices;usingnamespacemsclr;// a ref class that uses a com::ptr to contain an// IXMLDOMDocument object ref classXmlDocument { public:// construct the internal com::ptr with a null interface// and use CreateInstance to fill itXmlDocument(String^ progid) { m_ptrDoc.CreateInstance(progid); } // construct the internal com::ptr with a COM objectXmlDocument(IXMLDOMDocument* pDoc) : m_ptrDoc(pDoc) {} // note that the destructor will call the com::ptr destructor// and automatically release the reference to the COM objectprivate: com::ptr<IXMLDOMDocument> m_ptrDoc; }; // use the ref class to handle an XML DOM Document objectintmain() { IXMLDOMDocument* pDoc = NULL; try { // create an XML DOM document objectMarshal::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 objectcatch (Exception^ e) { Console::WriteLine(e); } finally { if (NULL != pDoc) { pDoc->Release(); } } }

ptr::~ptr

Destructs a com::ptr.

~ptr();

Remarks

On destruction, the com::ptr releases all references it owns to its COM object. Assuming that there are no other references held to the COM object, the COM object will be deleted and its memory freed.

Example

This example implements a CLR class that uses a com::ptr to wrap its private member IXMLDOMDocument object. In the main function, the two XmlDocument objects' destructors will be called when they go out of the scope of the try block, resulting in the underlying com::ptr destructor being called, releasing all owned references to the COM object.

// comptr_dtor.cpp// compile with: /clr /link msxml2.lib #include<msxml2.h> #include<msclr\com\ptr.h> #import<msxml3.dll> raw_interfaces_only usingnamespaceSystem;usingnamespaceSystem::Runtime::InteropServices;usingnamespacemsclr;// a ref class that uses a com::ptr to contain an// IXMLDOMDocument object ref classXmlDocument { public:// construct the internal com::ptr with a null interface// and use CreateInstance to fill itXmlDocument(String^ progid) { m_ptrDoc.CreateInstance(progid); } // construct the internal com::ptr with a COM objectXmlDocument(IXMLDOMDocument* pDoc) : m_ptrDoc(pDoc) {} // note that the destructor will call the com::ptr destructor// and automatically release the reference to the COM objectprivate: com::ptr<IXMLDOMDocument> m_ptrDoc; }; // use the ref class to handle an XML DOM Document objectintmain() { IXMLDOMDocument* pDoc = NULL; try { // create an XML DOM document objectMarshal::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 objectcatch (Exception^ e) { Console::WriteLine(e); } finally { if (NULL != pDoc) { pDoc->Release(); } } }

ptr::Attach

Attaches a COM object to a com::ptr.

voidAttach( _interface_type * _right );

Parameters

_right
The COM interface pointer to attach.

Exceptions

If the com::ptr already owns a reference to a COM object, Attach throws xref:System.InvalidOperationException.

Remarks

A call to Attach references the COM object but doesn't release the caller's reference to it.

Passing NULL to Attach results in no action being taken.

Example

This example implements a CLR class that uses a com::ptr to wrap its private member IXMLDOMDocument object. The ReplaceDocument member function first calls Release on any previously owned object and then calls Attach to attach a new document object.

// comptr_attach.cpp// compile with: /clr /link msxml2.lib #include<msxml2.h> #include<msclr\com\ptr.h> #import<msxml3.dll> raw_interfaces_only usingnamespaceSystem;usingnamespaceSystem::Runtime::InteropServices;usingnamespacemsclr;// a ref class that uses a com::ptr to contain an// IXMLDOMDocument object ref classXmlDocument { public:// construct the internal com::ptr with a null interface// and use CreateInstance to fill itXmlDocument(String^ progid) { m_ptrDoc.CreateInstance(progid); } // replace currently held COM object with another onevoidReplaceDocument(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 objectprivate: 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 objectintmain() { 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

Creates an instance of a COM object within a com::ptr.

voidCreateInstance( System::String ^ progid, LPUNKNOWN pouter, DWORD cls_context ); voidCreateInstance( System::String ^ progid, LPUNKNOWN pouter ); voidCreateInstance( System::String ^ progid ); voidCreateInstance( constwchar_t * progid, LPUNKNOWN pouter, DWORD cls_context ); voidCreateInstance( constwchar_t * progid, LPUNKNOWN pouter ); voidCreateInstance( constwchar_t * progid ); voidCreateInstance( REFCLSID rclsid, LPUNKNOWN pouter, DWORD cls_context ); voidCreateInstance( REFCLSID rclsid, LPUNKNOWN pouter ); voidCreateInstance( REFCLSID rclsid );

Parameters

progid
A ProgID string.

pouter
Pointer to the aggregate object's IUnknown interface (the controlling IUnknown). If pouter isn't specified, NULL is used.

cls_context
Context in which the code that manages the newly created object will run. The values are taken from the CLSCTX enumeration. If cls_context isn't specified, the value CLSCTX_ALL is used.

rclsid
CLSID associated with the data and code that will be used to create the object.

Exceptions

If the com::ptr already owns a reference to a COM object, CreateInstance throws xref:System.InvalidOperationException.

This function calls CoCreateInstance and uses xref:System.Runtime.InteropServices.Marshal.ThrowExceptionForHR%2A to convert any error HRESULT to an appropriate exception.

Remarks

CreateInstance uses CoCreateInstance to create a new instance of the specified object, identified either from a ProgID or a CLSID. The com::ptr references the newly created object and will automatically release all owned references upon destruction.

Example

This example implements a CLR class that uses a com::ptr to wrap its private member IXMLDOMDocument object. The class constructors use two different forms of CreateInstance to create the document object either from a ProgID or from a CLSID plus a CLSCTX.

// comptr_createinstance.cpp// compile with: /clr /link msxml2.lib #include<msxml2.h> #include<msclr\com\ptr.h> #import<msxml3.dll> raw_interfaces_only usingnamespaceSystem;usingnamespaceSystem::Runtime::InteropServices;usingnamespacemsclr;// a ref class that uses a com::ptr to contain an// IXMLDOMDocument object ref classXmlDocument { public:// construct the internal com::ptr with a null interface// and use CreateInstance to fill itXmlDocument(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 objectprivate: com::ptr<IXMLDOMDocument> m_ptrDoc; }; // use the ref class to handle an XML DOM Document objectintmain() { 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

Gives up ownership of the COM object, returning a pointer to the object.

_interface_type * Detach();

Return value

The pointer to the COM object.

If no object is owned, NULL is returned.

Exceptions

Internally, QueryInterface is called on the owned COM object and any error HRESULT is converted to an exception by xref:System.Runtime.InteropServices.Marshal.ThrowExceptionForHR%2A.

Remarks

Detach first adds a reference to the COM object on behalf of the caller and then releases all references owned by the com::ptr. The caller must ultimately release the returned object to destroy it.

Example

This example implements a CLR class that uses a com::ptr to wrap its private member IXMLDOMDocument object. The DetachDocument member function calls Detach to give up ownership of the COM object and return a pointer to the caller.

// comptr_detach.cpp// compile with: /clr /link msxml2.lib #include<msxml2.h> #include<msclr\com\ptr.h> #import<msxml3.dll> raw_interfaces_only usingnamespaceSystem;usingnamespaceSystem::Runtime::InteropServices;usingnamespacemsclr;// a ref class that uses a com::ptr to contain an// IXMLDOMDocument object ref classXmlDocument { public:// construct the internal com::ptr with a null interface// and use CreateInstance to fill itXmlDocument(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 objectprivate: 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 objectintmain() { 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 xmlMarshal::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

Returns a pointer to the owned COM object.

_interface_type * GetInterface();

Return value

A pointer to the owned COM object.

Exceptions

Internally, QueryInterface is called on the owned COM object and any error HRESULT is converted to an exception by xref:System.Runtime.InteropServices.Marshal.ThrowExceptionForHR%2A.

Remarks

The com::ptr adds a reference to the COM object on the caller's behalf and also keeps its own reference on the COM object. The caller must ultimately release the reference on the returned object or it will never be destroyed.

Example

This example implements a CLR class that uses a com::ptr to wrap its private member IXMLDOMDocument object. The GetDocument member function uses GetInterface to return a pointer to the COM object.

// comptr_getinterface.cpp// compile with: /clr /link msxml2.lib #include<msxml2.h> #include<msclr\com\ptr.h> #import<msxml3.dll> raw_interfaces_only usingnamespaceSystem;usingnamespaceSystem::Runtime::InteropServices;usingnamespacemsclr;// a ref class that uses a com::ptr to contain an// IXMLDOMDocument object ref classXmlDocument { public:// construct the internal com::ptr with a null interface// and use CreateInstance to fill itXmlDocument(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 nodevoidWriteDocument() { IXMLDOMNode* pNode = NULL; BSTR bstr = NULL; try { // use operator -> to call XML Doc memberMarshal::ThrowExceptionForHR(m_ptrDoc->get_firstChild(&pNode)); if (NULL != pNode) { // write out the xmlMarshal::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 objectprivate: 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 objectintmain() { 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 xmlMarshal::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

Queries the owned COM object for an interface and attaches the result to another com::ptr.

template<class_other_type> voidQueryInterface( ptr<_other_type> % other );

Parameters

other
The com::ptr that will get the interface.

Exceptions

Internally, QueryInterface is called on the owned COM object and any error HRESULT is converted to an exception by xref:System.Runtime.InteropServices.Marshal.ThrowExceptionForHR%2A.

Remarks

Use this method to create a COM wrapper for a different interface of the COM object owned by the current wrapper. This method calls QueryInterface through the owned COM object to request a pointer to a specific interface of the COM object and attaches the returned interface pointer to the passed-in com::ptr.

Example

This example implements a CLR class that uses a com::ptr to wrap its private member IXMLDOMDocument object. The WriteTopLevelNode member function uses QueryInterface to fill a local com::ptr with an IXMLDOMNode and then passes the com::ptr (by tracking reference) to a private member function that writes the node's name and text properties to the console.

// comptr_queryinterface.cpp// compile with: /clr /link msxml2.lib #include<msxml2.h> #include<msclr\com\ptr.h> #import<msxml3.dll> raw_interfaces_only usingnamespaceSystem;usingnamespaceSystem::Runtime::InteropServices;usingnamespacemsclr;// a ref class that uses a com::ptr to contain an// IXMLDOMDocument object ref classXmlDocument { public:// construct the internal com::ptr with a null interface// and use CreateInstance to fill itXmlDocument(String^ progid) { m_ptrDoc.CreateInstance(progid); } voidLoadXml(String^ xml) { pin_ptr<constwchar_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 functionMarshal::ThrowExceptionForHR(m_ptrDoc->loadXML(bstr, &bIsSuccessful)); } finally { ::SysFreeString(bstr); } } // write the top level node to the consolevoidWriteTopLevelNode() { 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 objectprivate:// simplified function that only writes the nodevoidWriteNode(com::ptr<IXMLDOMNode> % node) { BSTR bstr = NULL; try { // write out the name and text propertiesMarshal::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 objectintmain() { 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

Releases all owned references on the COM object.

voidRelease();

Remarks

Calling this function releases all owned references on the COM object and sets the internal handle to the COM object to nullptr. If no other references on the COM object exist, it will be destroyed.

Example

This example implements a CLR class that uses a com::ptr to wrap its private member IXMLDOMDocument object. The ReplaceDocument member function uses Release to release any prior document object before attaching the new document.

// comptr_release.cpp// compile with: /clr /link msxml2.lib #include<msxml2.h> #include<msclr\com\ptr.h> #import<msxml3.dll> raw_interfaces_only usingnamespaceSystem;usingnamespaceSystem::Runtime::InteropServices;usingnamespacemsclr;// a ref class that uses a com::ptr to contain an// IXMLDOMDocument object ref classXmlDocument { public:// construct the internal com::ptr with a null interface// and use CreateInstance to fill itXmlDocument(String^ progid) { m_ptrDoc.CreateInstance(progid); } // replace currently held COM object with another onevoidReplaceDocument(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 objectprivate: 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 objectintmain() { 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->

Member access operator, used to call methods on the owned COM object.

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

Return value

A smart_com_ptr to the COM object.

Exceptions

Internally, QueryInterface is called on the owned COM object and any error HRESULT is converted to an exception by xref:System.Runtime.InteropServices.Marshal.ThrowExceptionForHR%2A.

Remarks

This operator allows you to call methods of the owned COM object. It returns a temporary smart_com_ptr that automatically handles its own AddRef and Release.

Example

This example implements a CLR class that uses a com::ptr to wrap its private member IXMLDOMDocument object. The WriteDocument function uses operator-> to call the get_firstChild member of the document object.

// comptr_op_member.cpp// compile with: /clr /link msxml2.lib #include<msxml2.h> #include<msclr\com\ptr.h> #import<msxml3.dll> raw_interfaces_only usingnamespaceSystem;usingnamespaceSystem::Runtime::InteropServices;usingnamespacemsclr;// a ref class that uses a com::ptr to contain an// IXMLDOMDocument object ref classXmlDocument { public:// construct the internal com::ptr with a null interface// and use CreateInstance to fill itXmlDocument(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 nodevoidWriteDocument() { IXMLDOMNode* pNode = NULL; BSTR bstr = NULL; try { // use operator -> to call XML Doc memberMarshal::ThrowExceptionForHR(m_ptrDoc->get_firstChild(&pNode)); if (NULL != pNode) { // write out the xmlMarshal::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 objectprivate: 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 objectintmain() { 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 xmlMarshal::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=

Attaches a COM object to a com::ptr.

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

Parameters

_right
The COM interface pointer to attach.

Return value

A tracking reference on the com::ptr.

Exceptions

If the com::ptr already owns a reference to a COM object, operator= throws xref:System.InvalidOperationException.

Remarks

Assigning a COM object to a com::ptr references the COM object but doesn't release the caller's reference to it.

This operator has the same effect as Attach.

Example

This example implements a CLR class that uses a com::ptr to wrap its private member IXMLDOMDocument object. The ReplaceDocument member function first calls Release on any previously owned object and then uses operator= to attach a new document object.

// comptr_op_assign.cpp// compile with: /clr /link msxml2.lib #include<msxml2.h> #include<msclr\com\ptr.h> #import<msxml3.dll> raw_interfaces_only usingnamespaceSystem;usingnamespaceSystem::Runtime::InteropServices;usingnamespacemsclr;// a ref class that uses a com::ptr to contain an// IXMLDOMDocument object ref classXmlDocument { public:// construct the internal com::ptr with a null interface// and use CreateInstance to fill itXmlDocument(String^ progid) { m_ptrDoc.CreateInstance(progid); } // replace currently held COM object with another onevoidReplaceDocument(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 objectprivate: 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 objectintmain() { 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

Operator for using com::ptr in a conditional expression.

operatorbool();

Return value

true if the owned COM object is valid; false otherwise.

Remarks

The owned COM object is valid if it's not nullptr.

This operator converts to _detail_class::_safe_bool which is safer than bool because it can't be converted to an integral type.

Example

This example implements a CLR class that uses a com::ptr to wrap its private member IXMLDOMDocument object. The CreateInstance member function uses operator bool after creating the new document object to determine if it's valid and writes to the console if it is.

// comptr_op_bool.cpp// compile with: /clr /link msxml2.lib #include<msxml2.h> #include<msclr\com\ptr.h> #import<msxml3.dll> raw_interfaces_only usingnamespaceSystem;usingnamespaceSystem::Runtime::InteropServices;usingnamespacemsclr;// a ref class that uses a com::ptr to contain an// IXMLDOMDocument object ref classXmlDocument { public:voidCreateInstance(String^ progid) { if (!m_ptrDoc) { m_ptrDoc.CreateInstance(progid); if (m_ptrDoc) { // uses operator boolConsole::WriteLine("DOM Document created."); } } } // note that the destructor will call the com::ptr destructor// and automatically release the reference to the COM objectprivate: com::ptr<IXMLDOMDocument> m_ptrDoc; }; // use the ref class to handle an XML DOM Document objectintmain() { 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!

Operator to determine if the owned COM object is invalid.

booloperator!();

Return value

true if the owned COM object is invalid; false otherwise.

Remarks

The owned COM object is valid if it's not nullptr.

Example

This example implements a CLR class that uses a com::ptr to wrap its private member IXMLDOMDocument object. The CreateInstance member function uses operator! to determine if a document object is already owned, and only creates a new instance if the object is invalid.

// comptr_op_not.cpp// compile with: /clr /link msxml2.lib #include<msxml2.h> #include<msclr\com\ptr.h> #import<msxml3.dll> raw_interfaces_only usingnamespaceSystem;usingnamespaceSystem::Runtime::InteropServices;usingnamespacemsclr;// a ref class that uses a com::ptr to contain an// IXMLDOMDocument object ref classXmlDocument { public:voidCreateInstance(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 objectprivate: com::ptr<IXMLDOMDocument> m_ptrDoc; }; // use the ref class to handle an XML DOM Document objectintmain() { 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. 
close