Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Оболочка для 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.