com::ptr 클래스

CLR 클래스의 멤버로 사용할 수 있는 COM 개체에 대한 래퍼입니다. 이 래퍼는 또한 COM 개체의 수명 주기 관리를 자동화하여 소멸자가 호출될 때 개체에서 모든 소유 참조를 해제합니다. CComPtr 클래스와 유사합니다.

구문

template<class _interface_type>
ref class ptr;

매개 변수

_interface_type
COM 인터페이스.

설명

또한 com::ptr은 로컬 함수 변수로 사용하여 여러 COM 작업을 간소화하고 수명 주기 관리를 자동화할 수 있습니다.

A는 com::ptr 함수 매개 변수로 직접 사용할 수 없습니다. 대신 추적 참조 연산자 또는 개체에 대한 핸들 연산자(^)를 사용합니다.

A는 com::ptr 함수에서 직접 반환할 수 없으며 대신 핸들을 사용합니다.

예시

이 예제에서는 com::ptr을 사용해서 해당 개인 멤버 IXMLDOMDocument 개체를 래핑하는 CLR 클래스를 구현합니다. 클래스의 공용 메서드를 호출하면 포함된 IXMLDOMDocument 개체가 호출됩니다. 이 샘플은 XML 문서의 인스턴스를 만들고, 여기에 일부 간단한 XML을 채우고, 구문 분석된 문서 트리에서 간소화된 노드 작업을 수행하고 XML을 콘솔에 출력합니다.

// 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>

멤버

Public 생성자

속성 설명
ptr::ptr COM 개체를 com::ptr 래핑할 메서드를 생성합니다.
ptr::~ptr 를 소멸합니다 com::ptr.

공용 메서드

이름 설명
ptr::Attach COM 개체를 .에 연결합니다 com::ptr.
ptr::CreateInstance 내에 COM 개체의 인스턴스를 com::ptr만듭니다.
ptr::Detach COM 개체의 소유권을 포기하고 개체에 대한 포인터를 반환합니다.
ptr::GetInterface 내에 COM 개체의 인스턴스를 com::ptr만듭니다.
ptr::QueryInterface 소유 COM 개체에 인터페이스를 쿼리하고 결과를 다른 com::ptr개체에 연결합니다.
ptr::Release COM 개체에서 소유한 모든 참조를 해제합니다.

공용 연산자

이름 설명
ptr::operator-> 소유 COM 개체에서 메서드를 호출하는 데 사용되는 멤버 액세스 연산자입니다.
ptr::operator= COM 개체를 .에 연결합니다 com::ptr.
ptr::operator bool 조건식에서 사용하기 com::ptr 위한 연산자입니다.
ptr::operator! 소유된 COM 개체가 잘못된지 확인하는 연산자입니다.

요구 사항

헤더 파일<msclr\com\ptr.h>

네임스페이스 msclr::com

ptr::ptr

소유 COM 개체에 대한 포인터를 반환합니다.

ptr();
ptr(
   _interface_type * p
);

매개 변수

P
COM 인터페이스 포인터.

설명

인수 없는 생성자는 기본 개체 핸들에 할당됩니다 nullptr . 이후 호출은 com::ptr 내부 개체의 유효성을 검사하고 개체를 만들거나 연결할 때까지 자동으로 실패합니다.

한 인수 생성자는 COM 개체에 대한 참조를 추가하지만 호출자의 참조를 해제하지 않으므로 호출자는 COM 개체를 호출 Release 하여 컨트롤을 실제로 포기해야 합니다. 소멸자가 com::ptr호출되면 COM 개체에 대한 참조가 자동으로 해제됩니다.

이 생성자에 전달하는 NULL 것은 인수 없는 버전을 호출하는 것과 같습니다.

예시

이 예제에서는 com::ptr을 사용해서 해당 개인 멤버 IXMLDOMDocument 개체를 래핑하는 CLR 클래스를 구현합니다. 두 버전의 생성자를 모두 사용하는 방법을 보여 줍니다.

// 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

를 소멸합니다 com::ptr.

~ptr();

설명

소멸되면 COM 개체에 com::ptr 대한 모든 참조를 해제합니다. COM 개체에 대한 다른 참조가 없다고 가정하면 COM 개체가 삭제되고 해당 메모리가 해제됩니다.

예시

이 예제에서는 com::ptr을 사용해서 해당 개인 멤버 IXMLDOMDocument 개체를 래핑하는 CLR 클래스를 구현합니다. main 함수에서 두 XmlDocument 개체의 소멸자는 블록의 try 범위를 벗어날 때 호출되므로 기본 com::ptr 소멸자가 호출되어 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

COM 개체를 .에 연결합니다 com::ptr.

void Attach(
   _interface_type * _right
);

매개 변수

_오른쪽
연결할 COM 인터페이스 포인터입니다.

예외

COM 개체 Attachcom::ptr 대한 참조를 이미 소유하고 있는 경우 throw합니다InvalidOperationException.

설명

호출은 Attach COM 개체를 참조하지만 호출자의 참조를 해제하지는 않습니다.

결과를 전달 NULL 하면 Attach 아무 작업도 수행되지 않습니다.

예시

이 예제에서는 com::ptr을 사용해서 해당 개인 멤버 IXMLDOMDocument 개체를 래핑하는 CLR 클래스를 구현합니다. 멤버 함수는 ReplaceDocument 먼저 이전에 소유한 개체를 호출 Release 한 다음 새 문서 개체를 연결하기 위해 호출 Attach 합니다.

// 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

내에 COM 개체의 인스턴스를 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
);

매개 변수

progid
ProgID 문자열입니다.

pouter
집계 개체의 IUnknown 인터페이스(제어 IUnknown)에 대한 포인터입니다. pouter 지정 NULL 하지 않으면 사용됩니다.

cls_context
새로 만든 개체를 관리하는 코드가 실행되는 컨텍스트입니다. 값은 열거형에서 CLSCTX 가져옵니다. 지정하지 않으면 cls_context CLSCTX_ALL 값이 사용됩니다.

rclsid
CLSID 개체를 만드는 데 사용할 데이터 및 코드와 연결됩니다.

예외

COM 개체 CreateInstancecom::ptr 대한 참조를 이미 소유하고 있는 경우 throw합니다InvalidOperationException.

이 함수는 오류를 호출 CoCreateInstance 하고 사용하여 ThrowExceptionForHR 오류를 HRESULT 적절한 예외로 변환합니다.

설명

CreateInstance 에서는 CoCreateInstance ProgID 또는 CLSID에서 식별된 지정된 개체의 새 인스턴스를 만듭니다. 새로 com::ptr 만든 개체를 참조하고 소멸 시 소유된 모든 참조를 자동으로 해제합니다.

예시

이 예제에서는 com::ptr을 사용해서 해당 개인 멤버 IXMLDOMDocument 개체를 래핑하는 CLR 클래스를 구현합니다. 클래스 생성자는 ProgID 또는 CLSID와 CLSCTX에서 문서 개체를 만드는 두 가지 형식 CreateInstance 을 사용합니다.

// 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

COM 개체의 소유권을 포기하고 개체에 대한 포인터를 반환합니다.

_interface_type * Detach();

반환 값

COM 개체에 대한 포인터입니다.

소유된 개체가 없으면 NULL이 반환됩니다.

예외

내부적으로 소유 QueryInterface COM 개체에서 호출되고 오류가 HRESULT 예외 ThrowExceptionForHR로 변환됩니다.

설명

Detach 먼저 호출자를 대신하여 COM 개체에 대한 참조를 추가한 다음 소유하는 모든 참조를 com::ptr해제합니다. 호출자는 궁극적으로 반환된 개체를 해제하여 삭제해야 합니다.

예시

이 예제에서는 com::ptr을 사용해서 해당 개인 멤버 IXMLDOMDocument 개체를 래핑하는 CLR 클래스를 구현합니다. 멤버 함수는 DetachDocument COM 개체의 소유권을 포기하고 호출자에 대한 포인터를 반환하기 위해 호출 Detach 합니다.

// 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

소유 COM 개체에 대한 포인터를 반환합니다.

_interface_type * GetInterface();

반환 값

소유 COM 개체에 대한 포인터입니다.

예외

내부적으로 소유 QueryInterface COM 개체에서 호출되고 오류가 HRESULT 예외 ThrowExceptionForHR로 변환됩니다.

설명

com::ptr 호출자를 대신하여 COM 개체에 대한 참조를 추가하고 COM 개체에 대한 자체 참조도 유지합니다. 호출자는 궁극적으로 반환된 개체에 대한 참조를 해제해야 합니다. 그렇지 않으면 제거되지 않습니다.

예시

이 예제에서는 com::ptr을 사용해서 해당 개인 멤버 IXMLDOMDocument 개체를 래핑하는 CLR 클래스를 구현합니다. 멤버 함수는 GetDocument COM 개체에 대한 포인터를 반환하는 데 사용합니다 GetInterface .

// 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

소유 COM 개체에 인터페이스를 쿼리하고 결과를 다른 com::ptr개체에 연결합니다.

template<class _other_type>
void QueryInterface(
   ptr<_other_type> % other
);

매개 변수

기타
인터페이스 com::ptr 를 가져올 것입니다.

예외

내부적으로 소유 QueryInterface COM 개체에서 호출되고 오류가 HRESULT 예외 ThrowExceptionForHR로 변환됩니다.

설명

이 메서드를 사용하여 현재 래퍼가 소유한 COM 개체의 다른 인터페이스에 대한 COM 래퍼를 만듭니다. 이 메서드는 소유 COM 개체를 통해 호출 QueryInterface 하여 COM 개체의 특정 인터페이스에 대한 포인터를 요청하고 반환된 인터페이스 포인터를 전달된 인터페이스 포인터에 com::ptr연결합니다.

예시

이 예제에서는 com::ptr을 사용해서 해당 개인 멤버 IXMLDOMDocument 개체를 래핑하는 CLR 클래스를 구현합니다. 멤버 함수 QueryInterfaceWriteTopLevelNode 로컬 com::ptrIXMLDOMNode 을 입력한 다음(참조를 추적하여) 노드의 이름과 텍스트 속성을 콘솔에 쓰는 프라이빗 멤버 함수에 전달 com::ptr 합니다.

// 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

COM 개체에서 소유한 모든 참조를 해제합니다.

void Release();

설명

이 함수를 호출하면 COM 개체에 대한 모든 소유 참조가 해제되고 내부 핸들이 COM 개체로 설정됩니다 nullptr. COM 개체에 대한 다른 참조가 없으면 제거됩니다.

예시

이 예제에서는 com::ptr을 사용해서 해당 개인 멤버 IXMLDOMDocument 개체를 래핑하는 CLR 클래스를 구현합니다. 멤버 함수는 ReplaceDocument 새 문서를 첨부하기 전에 이전 문서 개체를 해제하는 데 사용합니다 Release .

// 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->

소유 COM 개체에서 메서드를 호출하는 데 사용되는 멤버 액세스 연산자입니다.

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

반환 값

COM 개체에 대한 A smart_com_ptr 입니다.

예외

내부적으로 소유 QueryInterface COM 개체에서 호출되고 오류가 HRESULT 예외 ThrowExceptionForHR로 변환됩니다.

설명

이 연산자를 사용하면 소유 COM 개체의 메서드를 호출할 수 있습니다. 자체 및 을 자동으로 처리하는 임시 smart_com_ptr 를 반환합니다 AddRefRelease.

예시

이 예제에서는 com::ptr을 사용해서 해당 개인 멤버 IXMLDOMDocument 개체를 래핑하는 CLR 클래스를 구현합니다. 이 함수는 WriteDocument 문서 개체의 멤버를 get_firstChild 호출하는 데 사용합니다operator->.

// 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=

COM 개체를 .에 연결합니다 com::ptr.

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

매개 변수

_오른쪽
연결할 COM 인터페이스 포인터입니다.

반환 값

에 대한 추적 참조입니다 com::ptr.

예외

COM 개체 operator=com::ptr 대한 참조를 이미 소유하고 있는 경우 throw합니다InvalidOperationException.

설명

COM 개체를 COM 개체에 com::ptr 할당하면 COM 개체가 참조되지만 해당 개체에 대한 호출자의 참조는 해제되지 않습니다.

이 연산자는 .Attach

예시

이 예제에서는 com::ptr을 사용해서 해당 개인 멤버 IXMLDOMDocument 개체를 래핑하는 CLR 클래스를 구현합니다. 멤버 함수는 ReplaceDocument 먼저 이전에 소유한 개체를 호출 Release 한 다음 새 문서 개체를 연결하는 데 사용합니다 operator= .

// 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

조건식에서 사용하기 com::ptr 위한 연산자입니다.

operator bool();

반환 값

true 소유 COM 개체가 유효한 경우 false 그렇지 않으면.

설명

소유 COM 개체가 아닌 nullptr경우 유효합니다.

이 연산자는 정수 계열 형식으로 _detail_class::_safe_bool 변환할 수 없기 때문에 보다 bool 안전한 것으로 변환됩니다.

예시

이 예제에서는 com::ptr을 사용해서 해당 개인 멤버 IXMLDOMDocument 개체를 래핑하는 CLR 클래스를 구현합니다. 멤버 함수는 CreateInstance 새 문서 개체를 만든 후 해당 개체가 유효한지 확인하고 콘솔에 쓰는 경우 사용합니다 operator bool .

// 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!

소유된 COM 개체가 잘못된지 확인하는 연산자입니다.

bool operator!();

반환 값

true 소유 COM 개체가 잘못되었으면 false 그렇지 않으면.

설명

소유 COM 개체가 아닌 nullptr경우 유효합니다.

예시

이 예제에서는 com::ptr을 사용해서 해당 개인 멤버 IXMLDOMDocument 개체를 래핑하는 CLR 클래스를 구현합니다. 멤버 함수는 CreateInstance 문서 개체가 이미 소유되어 있는지 여부를 확인하는 데 사용 operator! 하며 개체가 잘못된 경우에만 새 인스턴스를 만듭니다.

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