Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Оболочка для COM-объекта, который можно использовать в качестве члена класса CLR. Оболочка также автоматизирует управление временем существования 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-объекта в пределах 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.
Замечания
Конструктор no-argument назначает nullptr
дескриптор базового объекта. Последующие com::ptr
вызовы будут проверять внутренний объект и автоматически завершать сбой, пока объект не будет создан или присоединен.
Конструктор one-argument добавляет ссылку на COM-объект, но не освобождает ссылку вызывающего объекта, поэтому вызывающий объект должен вызывать Release
com-объект, чтобы действительно отказаться от управления. 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-объекта в пределах 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
.
зобастый голубь
Указатель на интерфейс 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-объект от имени вызывающего объекта, а также сохраняет собственную ссылку на 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-объекта, принадлежащих текущему оболочке. Этот метод вызывает QueryInterface
через собственный COM-объект, чтобы запросить указатель на определенный интерфейс com-объекта и присоединяет возвращаемый указатель интерфейса к переданной com::ptr
.
Пример
В этом примере реализуется класс CLR, который использует com::ptr
для упаковки своего частного объекта-члена IXMLDOMDocument
. Функция-член WriteTopLevelNode
используется QueryInterface
для заполнения локального объекта IXMLDOMNode
com::ptr
, а затем передает 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-объект com::ptr
, но не освобождает ссылку вызывающего объекта.
Этот оператор имеет тот же эффект, что 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
так.
Этот оператор преобразуется в _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
так.
Пример
В этом примере реализуется класс 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.