com::ptr 類別
可當做 CLR 類別成員使用之 COM 物件的包裝函式。 包裝函式也會將 COM 物件的存留期管理自動化,在呼叫其解構函式時,釋出物件上所有已擁有的參考。 類似於 CComPtr 類別。
語法
template<class _interface_type>
ref class ptr;
參數
_interface_type
COM 介面。
備註
com::ptr
也可以當做本機函式變數使用,以簡化各種 COM 工作並且將存留期管理自動化。
com::ptr
不能直接當做函式參數使用;請改用追蹤參考運算符或物件運算子句柄 (^) 。
無法直接從函式傳回 , com::ptr
請改用句柄。
範例
這個範例實作 CLR 類別,此類別使用 com::ptr
來包裝其私用成員 IXMLDOMDocument
物件。 呼叫類別的公用方法會造成對包含的 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>
成員
公用建構函式
名稱 | 描述 |
---|---|
ptr::ptr | com::ptr 建構 以包裝 COM 物件。 |
ptr::~ptr | 解 com::ptr 構 。 |
公用方法
名稱 | 描述 |
---|---|
ptr::Attach | 將 COM 物件附加至 com::ptr 。 |
ptr::CreateInstance | 在內 com::ptr 建立 COM 對象的實例。 |
ptr::Detach | 放棄 COM 對象的擁有權,並傳回物件的指標。 |
ptr::GetInterface | 在內 com::ptr 建立 COM 對象的實例。 |
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 的介面指標。
備註
no-argument 建構函式會 nullptr
指派給基礎物件句柄。 未來對的 com::ptr
呼叫將會驗證內部物件,並在建立或附加物件之前以無訊息方式失敗。
one 自變數建構函式會將參考新增至 COM 物件,但不會釋放呼叫端的參考,因此呼叫端必須在 COM 物件上呼叫 Release
,才能真正放棄控件。 com::ptr
呼叫 的解構函式時,它會自動在 COM 對象上釋放其參考。
傳遞 NULL
至這個建構函式與呼叫 no-argument 版本相同。
範例
這個範例實作 CLR 類別,此類別使用 com::ptr
來包裝其私用成員 IXMLDOMDocument
物件。 它示範這兩個建構函式版本的使用方式。
// 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::ptr
會釋放它所擁有的 COM 物件的所有參考。 假設 COM 物件沒有其他保留的參考,將會刪除 COM 物件並釋放其記憶體。
範例
這個範例實作 CLR 類別,此類別使用 com::ptr
來包裝其私用成員 IXMLDOMDocument
物件。 在函式中 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::ptr
如果已經擁有 COM 物件的參考,Attach
則會InvalidOperationException擲回 。
備註
參考 Attach
COM 物件的呼叫,但不會釋放呼叫端對它的參考。
傳遞 NULL
至 Attach
會導致不採取任何動作。
範例
這個範例實作 CLR 類別,此類別使用 com::ptr
來包裝其私用成員 IXMLDOMDocument
物件。 成員 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::ptr
建立 COM 對象的實例。
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::ptr
如果已經擁有 COM 物件的參考,CreateInstance
則會InvalidOperationException擲回 。
此函式會呼叫 CoCreateInstance
並使用 ThrowExceptionForHR ,將任何錯誤 HRESULT
轉換成適當的例外狀況。
備註
CreateInstance
會使用 CoCreateInstance
建立指定物件的新實例,從 ProgID 或 CLSID 識別。 參考 com::ptr
新建立的物件,而且會在解構時自動釋放所有擁有的參考。
範例
這個範例實作 CLR 類別,此類別使用 com::ptr
來包裝其私用成員 IXMLDOMDocument
物件。 類別建構函式會使用兩種不同的 形式 CreateInstance
,從 ProgID 或 CLSID 加上 CLSCTX 建立文件物件。
// 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
擁有的所有參考。 呼叫端最終必須釋放傳回的物件,才能終結它。
範例
這個範例實作 CLR 類別,此類別使用 com::ptr
來包裝其私用成員 IXMLDOMDocument
物件。 成員 DetachDocument
函式會呼叫 Detach
以放棄 COM 物件的擁有權,並傳回呼叫端的指標。
// 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 物件上保留自己的參考。 呼叫端最終必須在傳回的對象上釋放參考,否則永遠不會被終結。
範例
這個範例實作 CLR 類別,此類別使用 com::ptr
來包裝其私用成員 IXMLDOMDocument
物件。 成員 GetDocument
函式會使用 GetInterface
傳回 COM 物件的指標。
// 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
);
參數
other
com::ptr
取得介面的 。
例外狀況
在內部,QueryInterface
會在擁有的 COM 物件上呼叫 ,而且任何錯誤HRESULT
會轉換成 的例外狀況。ThrowExceptionForHR
備註
使用這個方法,為目前包裝函式所擁有的 COM 物件之不同介面建立 COM 包裝函式。 這個方法會透過擁有的 COM 物件呼叫 QueryInterface
,以要求 COM 物件之特定介面的指標,並將傳回的介面指標附加至傳入 com::ptr
的 。
範例
這個範例實作 CLR 類別,此類別使用 com::ptr
來包裝其私用成員 IXMLDOMDocument
物件。 成員 WriteTopLevelNode
函式會使用 QueryInterface
來填滿本機 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 對象上沒有任何其他參考存在,則會終結它。
範例
這個範例實作 CLR 類別,此類別使用 com::ptr
來包裝其私用成員 IXMLDOMDocument
物件。 成員 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->();
傳回值
smart_com_ptr
COM 物件的 。
例外狀況
在內部,QueryInterface
會在擁有的 COM 物件上呼叫 ,而且任何錯誤HRESULT
會轉換成 的例外狀況。ThrowExceptionForHR
備註
這個運算子可讓您呼叫擁有之 COM 物件的方法。 它會傳回暫時, smart_com_ptr
自動處理自己的 AddRef
和 Release
。
範例
這個範例實作 CLR 類別,此類別使用 com::ptr
來包裝其私用成員 IXMLDOMDocument
物件。 函 WriteDocument
式會使用 operator->
來呼叫 get_firstChild
檔對象的成員。
// 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::ptr
如果已經擁有 COM 物件的參考,operator=
則會InvalidOperationException擲回 。
備註
將 COM 物件指派給 com::ptr
參考 COM 物件,但不會釋放呼叫者的參考。
這個運算子的效果與 Attach
相同。
範例
這個範例實作 CLR 類別,此類別使用 com::ptr
來包裝其私用成員 IXMLDOMDocument
物件。 成員 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
,則擁有的 COM 物件有效。
這個運算子會 _detail_class::_safe_bool
轉換成比更安全 bool
的 運算子,因為它無法轉換成整數類型。
範例
這個範例實作 CLR 類別,此類別使用 com::ptr
來包裝其私用成員 IXMLDOMDocument
物件。 成員 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 物件有效。
範例
這個範例實作 CLR 類別,此類別使用 com::ptr
來包裝其私用成員 IXMLDOMDocument
物件。 成員 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.