Share via


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 ThrowExceptionForHR.

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

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();
      }
      
   }
}

Requirements

Header file <msclr\com\ptr.h>

Namespace msclr::com

See Also

Reference

ptr::Release

ptr::Attach

Other Resources

ptr Members