description | title | ms.date | ms.topic | f1_keywords | helpviewer_keywords | ms.assetid | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Learn more about: com::ptr Class | com::ptr Class | 01/16/2019 | reference |
|
| 0144d0e4-919c-45f9-a3f8-fbc9edba32bf |
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.
template<class _interface_type> ref class ptr;
_interface_type
COM interface.
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.
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>
Name | Description |
---|---|
ptr::ptr | Constructs a com::ptr to wrap a COM object. |
ptr::~ptr | Destructs a com::ptr . |
Name | Description |
---|---|
ptr::Attach | Attaches a COM object to a com::ptr . |
ptr::CreateInstance | Creates an instance of a COM object within a com::ptr . |
ptr::Detach | Gives up ownership of the COM object, returning a pointer to the object. |
ptr::GetInterface | Creates an instance of a COM object within a com::ptr . |
ptr::QueryInterface | Queries the owned COM object for an interface and attaches the result to another com::ptr . |
ptr::Release | Releases all owned references on the COM object. |
Name | Description |
---|---|
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 bool | Operator for using com::ptr in a conditional expression. |
ptr::operator! | Operator to determine if the owned COM object is invalid. |
Header file <msclr\com\ptr.h>
Namespace msclr::com
Returns a pointer to the owned COM object.
ptr(); ptr( _interface_type * p );
P
A COM interface pointer.
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.
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(); } } }
Destructs a com::ptr
.
~ptr();
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.
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(); } } }
Attaches a COM object to a com::ptr
.
voidAttach( _interface_type * _right );
_right
The COM interface pointer to attach.
If the com::ptr
already owns a reference to a COM object, Attach
throws xref:System.InvalidOperationException.
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.
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(); } } }
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 );
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.
rclsidCLSID
associated with the data and code that will be used to create the object.
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.
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.
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); } }
Gives up ownership of the COM object, returning a pointer to the object.
_interface_type * Detach();
The pointer to the COM object.
If no object is owned, NULL is returned.
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.
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.
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(); } } }
Returns a pointer to the owned COM object.
_interface_type * GetInterface();
A pointer to the owned COM object.
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.
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.
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>
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 );
other
The com::ptr
that will get the interface.
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.
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
.
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>
Releases all owned references on the COM object.
voidRelease();
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.
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(); } } }
Member access operator, used to call methods on the owned COM object.
_detail::smart_com_ptr<_interface_type> operator->();
A smart_com_ptr
to the COM object.
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.
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
.
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>
Attaches a COM object to a com::ptr
.
ptr<_interface_type> % operator=( _interface_type * _right );
_right
The COM interface pointer to attach.
A tracking reference on the com::ptr
.
If the com::ptr
already owns a reference to a COM object, operator=
throws xref:System.InvalidOperationException.
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
.
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(); } } }
Operator for using com::ptr
in a conditional expression.
operatorbool();
true
if the owned COM object is valid; false
otherwise.
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.
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.
Operator to determine if the owned COM object is invalid.
booloperator!();
true
if the owned COM object is invalid; false
otherwise.
The owned COM object is valid if it's not nullptr
.
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.