Classe com::ptr
Um wrapper para um objeto COM que pode ser usado como membro de uma classe CLR. O wrapper também automatiza o gerenciamento de tempo de vida do objeto COM, liberando todas as referências de propriedade no objeto quando seu destruidor é chamado. Análogo à classe CComPtr.
Sintaxe
template<class _interface_type>
ref class ptr;
Parâmetros
_interface_type
Interface COM.
Comentários
Um com::ptr
também pode ser usado como uma variável de função local para simplificar várias tarefas COM e automatizar o gerenciamento de tempo de vida.
Um com::ptr
não pode ser usado diretamente como um parâmetro de função. Use um Operador de referência de acompanhamento ou um Identificador para o operador do objeto (^).
Um com::ptr
não pode retornar diretamente de uma função. Use um identificador.
Exemplo
Este exemplo implementa uma classe CLR que usa um com::ptr
para encapsular seu objeto IXMLDOMDocument
de membro privado. Chamar os métodos públicos da classe resulta em chamadas para o objeto IXMLDOMDocument
contido. O exemplo cria uma instância de um documento XML, preenche-o com um XML simples e faz uma caminhada simplificada dos nós na árvore de documentos analisada para imprimir o XML no console.
// 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>
Membros
Construtores públicos
Nome | Descrição |
---|---|
ptr::ptr | Constrói um com::ptr para encapsular um objeto COM. |
ptr::~ptr | Destrói um com::ptr . |
Métodos públicos
Nome | Descrição |
---|---|
ptr::Attach | Anexa um objeto COM a um com::ptr . |
ptr::CreateInstance | Cria uma instância de um objeto COM em um com::ptr . |
ptr::Detach | Desiste da propriedade do objeto COM, retornando um ponteiro para o objeto. |
ptr::GetInterface | Cria uma instância de um objeto COM em um com::ptr . |
ptr::QueryInterface | Consulta o objeto COM de propriedade de uma interface e anexa o resultado a outro com::ptr . |
ptr::Release | Libera todas as referências de propriedade no objeto COM. |
Operadores públicos
Nome | Descrição |
---|---|
ptr::operator-> |
Operador de acesso de membro, usado para chamar métodos no objeto COM de propriedade. |
ptr::operator= | Anexa um objeto COM a um com::ptr . |
ptr::operator bool | Operador para uso de com::ptr em uma expressão condicional. |
ptr::operator! | Operador para determinar se o objeto COM de propriedade é inválido. |
Requisitos
Arquivo de cabeçalho<msclr\com\ptr.h>
Namespace msclr::com
ptr::ptr
Retorna um ponteiro para o objeto COM de propriedade.
ptr();
ptr(
_interface_type * p
);
Parâmetros
P
Um ponteiro de interface COM.
Comentários
O construtor sem argumento atribui nullptr
ao identificador de objeto subjacente. Chamadas futuras para com::ptr
validará o objeto interno e falharão silenciosamente até que um objeto seja criado ou anexado.
O construtor de um argumento adiciona uma referência ao objeto COM, mas não libera a referência do chamador, portanto, o chamador precisa chamar Release
no objeto COM para realmente desistir do controle. Quando o com::ptr
do destruidor for chamado, ele liberará automaticamente suas referências no objeto COM.
Passar NULL
para esse construtor é igual a chamar a versão sem argumento.
Exemplo
Este exemplo implementa uma classe CLR que usa um com::ptr
para encapsular seu objeto IXMLDOMDocument
de membro privado. Ele demonstra o uso de ambas as versões do construtor.
// 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
Destrói um com::ptr
.
~ptr();
Comentários
Na destruição, as versões de com::ptr
são todas referências que ela possui ao objeto COM. Supondo que não haja outras referências mantidas no objeto COM, ele será excluído e sua memória será liberada.
Exemplo
Este exemplo implementa uma classe CLR que usa um com::ptr
para encapsular seu objeto IXMLDOMDocument
de membro privado. Na função main
, os destruidores dos dois objetos XmlDocument
serão chamados quando saírem do escopo do bloco try
, resultando na chamada do destruidor com::ptr
subjacente, o que libera todas as referências de propriedade para o objeto 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
Anexa um objeto COM a um com::ptr
.
void Attach(
_interface_type * _right
);
Parâmetros
_right
O ponteiro da interface COM a ser anexado.
Exceções
Se com::ptr
já possui uma referência a um objeto COM, Attach
lança InvalidOperationException.
Comentários
Uma chamada para Attach
referencia o objeto COM, mas não libera a referência do chamador a ele.
Passar NULL
para Attach
resulta em nenhuma ação tomada.
Exemplo
Este exemplo implementa uma classe CLR que usa um com::ptr
para encapsular seu objeto IXMLDOMDocument
de membro privado. A função membro ReplaceDocument
primeiro chama Release
em qualquer objeto de propriedade anterior e, em seguida, chama Attach
para anexar um novo objeto de documento.
// 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
Cria uma instância de um objeto COM em um 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
);
Parâmetros
progid
Uma cadeia de caracteres ProgID
.
pouter
Ponteiro para a interface IUnknown do objeto agregado (o IUnknown de controle). Se pouter
não for especificado, NULL
será usado.
cls_context
Contexto em que o código que gerencia o objeto recém-criado executará. Os valores válidos são obtidos da enumeração CLSCTX
. Se cls_context
não for especificado, o valor CLSCTX_ALL será usado.
rclsid
CLSID
associado aos dados e ao código que serão usados para criar o objeto.
Exceções
Se com::ptr
já possui uma referência a um objeto COM, CreateInstance
lança InvalidOperationException.
Essa função chama CoCreateInstance
e usa ThrowExceptionForHR para converter qualquer erro HRESULT
em uma exceção apropriada.
Comentários
CreateInstance
usa CoCreateInstance
para criar uma nova instância do objeto especificado, identificada a partir de um ProgID ou de um CLSID. O com::ptr
referencia ao objeto recém-criado e libera automaticamente todas as referências de propriedade após a destruição.
Exemplo
Este exemplo implementa uma classe CLR que usa um com::ptr
para encapsular seu objeto IXMLDOMDocument
de membro privado. Os construtores de classe usam duas formas diferentes de CreateInstance
para criar o objeto de documento a partir de um ProgID ou de um CLSID mais um 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
Desiste da propriedade do objeto COM, retornando um ponteiro para o objeto.
_interface_type * Detach();
Valor retornado
O ponteiro para um objeto COM.
Se nenhum objeto for de propriedade, NULL será retornado.
Exceções
Internamente, QueryInterface
é chamado no objeto COM de propriedade e qualquer erro HRESULT
é convertido em uma exceção por ThrowExceptionForHR.
Comentários
Detach
primeiro adiciona uma referência ao objeto COM em nome do chamador e, em seguida, libera todas as referências pertencentes ao com::ptr
. O chamador precisa, em última análise, liberar o objeto retornado para destruí-lo.
Exemplo
Este exemplo implementa uma classe CLR que usa um com::ptr
para encapsular seu objeto IXMLDOMDocument
de membro privado. A função membro DetachDocument
chama Detach
para abrir mão da propriedade do objeto COM e retornar um ponteiro para o chamador.
// 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
Retorna um ponteiro para o objeto COM de propriedade.
_interface_type * GetInterface();
Valor retornado
Um ponteiro para o objeto COM de propriedade.
Exceções
Internamente, QueryInterface
é chamado no objeto COM de propriedade e qualquer erro HRESULT
é convertido em uma exceção por ThrowExceptionForHR.
Comentários
O com::ptr
adiciona uma referência ao objeto COM ao nome do chamador e também mantém sua própria referência no objeto COM. O chamador precisa, em última análise, liberar a referência no objeto retornado ou nunca será destruída.
Exemplo
Este exemplo implementa uma classe CLR que usa um com::ptr
para encapsular seu objeto IXMLDOMDocument
de membro privado. A função membro GetDocument
usa GetInterface
para retornar um ponteiro para o objeto 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
Consulta o objeto COM de propriedade de uma interface e anexa o resultado a outro com::ptr
.
template<class _other_type>
void QueryInterface(
ptr<_other_type> % other
);
Parâmetros
other
O com::ptr
que obterá a interface.
Exceções
Internamente, QueryInterface
é chamado no objeto COM de propriedade e qualquer erro HRESULT
é convertido em uma exceção por ThrowExceptionForHR.
Comentários
Use esse método para criar um wrapper COM para uma interface diferente do objeto COM pertencente ao wrapper atual. Esse método chama QueryInterface
por meio do objeto COM de propriedade para solicitar um ponteiro para uma interface específica do objeto COM e anexa o ponteiro de interface retornado ao com::ptr
passado.
Exemplo
Este exemplo implementa uma classe CLR que usa um com::ptr
para encapsular seu objeto IXMLDOMDocument
de membro privado. A função membro WriteTopLevelNode
usa QueryInterface
para preencher um com::ptr
local com um IXMLDOMNode
e, em seguida, passa a com::ptr
(por referência de rastreamento) para uma função de membro privado que grava o nome do nó e as propriedades de texto no console.
// 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
Libera todas as referências de propriedade no objeto COM.
void Release();
Comentários
Chamar essa função libera todas as referências de propriedade no objeto COM e define o identificador interno do objeto COM como nullptr
. Se nenhuma outra referência no objeto COM existir, ela será destruída.
Exemplo
Este exemplo implementa uma classe CLR que usa um com::ptr
para encapsular seu objeto IXMLDOMDocument
de membro privado. A função membro ReplaceDocument
usa Release
para liberar qualquer objeto de documento anterior antes de anexar o novo documento.
// 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->
Operador de acesso de membro, usado para chamar métodos no objeto COM de propriedade.
_detail::smart_com_ptr<_interface_type> operator->();
Valor retornado
Um smart_com_ptr
para o objeto COM.
Exceções
Internamente, QueryInterface
é chamado no objeto COM de propriedade e qualquer erro HRESULT
é convertido em uma exceção por ThrowExceptionForHR.
Comentários
Esse operador permite chamar métodos do objeto COM de propriedade. Ele retorna um smart_com_ptr
temporário que manipula automaticamente seu próprio AddRef
e Release
.
Exemplo
Este exemplo implementa uma classe CLR que usa um com::ptr
para encapsular seu objeto IXMLDOMDocument
de membro privado. A função WriteDocument
usa operator->
para chamar o membro get_firstChild
do objeto do documento.
// 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=
Anexa um objeto COM a um com::ptr
.
ptr<_interface_type> % operator=(
_interface_type * _right
);
Parâmetros
_right
O ponteiro da interface COM a ser anexado.
Valor retornado
Uma referência de rastreamento no com::ptr
.
Exceções
Se com::ptr
já possui uma referência a um objeto COM, operator=
lança InvalidOperationException.
Comentários
Atribuir um objeto COM a um com::ptr
referencia o objeto COM, mas não libera a referência do chamador a ele.
Esse operador tem o mesmo efeito que Attach
.
Exemplo
Este exemplo implementa uma classe CLR que usa um com::ptr
para encapsular seu objeto IXMLDOMDocument
de membro privado. A função membro ReplaceDocument
primeiro chama Release
em qualquer objeto de propriedade anterior e, em seguida, usa operator=
para anexar um novo objeto de documento.
// 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
Operador para uso de com::ptr
em uma expressão condicional.
operator bool();
Valor retornado
true
se o objeto COM de propriedade for válido; false
, caso contrário.
Comentários
O objeto COM de propriedade será válido se não for nullptr
.
Esse operador é convertido em _detail_class::_safe_bool
, que é mais seguro do que bool
porque ele não pode ser convertido em um tipo integral.
Exemplo
Este exemplo implementa uma classe CLR que usa um com::ptr
para encapsular seu objeto IXMLDOMDocument
de membro privado. A função membro CreateInstance
usa operator bool
depois de criar o novo objeto de documento para determinar se ele é válido e grava no console, caso seja.
// 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!
Operador para determinar se o objeto COM de propriedade é inválido.
bool operator!();
Valor retornado
true
se o objeto COM de propriedade for inválido; false
, caso contrário.
Comentários
O objeto COM de propriedade será válido se não for nullptr
.
Exemplo
Este exemplo implementa uma classe CLR que usa um com::ptr
para encapsular seu objeto IXMLDOMDocument
de membro privado. A função membro CreateInstance
usa operator!
para determinar se um objeto de documento já é de propriedade e só cria uma nova instância se o objeto for inválido.
// 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.