Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Оболочка для 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.