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 개체 Attach
에 com::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 개체 CreateInstance
에 com::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 클래스를 구현합니다. 멤버 함수 QueryInterface
는 WriteTopLevelNode
로컬 com::ptr
IXMLDOMNode
을 입력한 다음(참조를 추적하여) 노드의 이름과 텍스트 속성을 콘솔에 쓰는 프라이빗 멤버 함수에 전달 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
를 반환합니다 AddRef
Release
.
예시
이 예제에서는 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.
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기