com::ptr — Klasa
Otoka obiektu COM, który może być używany jako element członkowski klasy CLR. Otoka automatyzuje również zarządzanie okresem istnienia obiektu COM, zwalniając wszystkie odwołania należące do obiektu, gdy jego destruktor jest wywoływany. Analogicznie do klasy CComPtr.
Składnia
template<class _interface_type>
ref class ptr;
Parametry
_interface_type
Interfejs COM.
Uwagi
Można com::ptr
również użyć jako zmiennej funkcji lokalnej, aby uprościć różne zadania MODELU COM i zautomatyzować zarządzanie okresem istnienia.
Nie com::ptr
można użyć elementu bezpośrednio jako parametru funkcji. Zamiast tego użyj operatora odwołania śledzenia lub operatora Dojścia do obiektu (^).
com::ptr
Nie można bezpośrednio zwrócić elementu z funkcji; zamiast tego użyj uchwytu.
Przykład
W tym przykładzie implementuje klasę CLR, która używa klasy com::ptr
do zawijania jej prywatnego obiektu członkowskiego IXMLDOMDocument
. Wywołanie publicznych metod klasy powoduje wywołania zawartego IXMLDOMDocument
obiektu. Przykład tworzy wystąpienie dokumentu XML, wypełnia go prostym kodem XML i wykonuje uproszczony przewodnik węzłów w przeanalizowanym drzewie dokumentów, aby wydrukować kod XML w konsoli programu .
// 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>
Elementy członkowskie
Konstruktory publiczne
Nazwa | Opis |
---|---|
ptr::p tr | Tworzy obiekt com::ptr COM w celu opakowania obiektu COM. |
ptr::~ptr | Destrukuje element com::ptr . |
Metody publiczne
Nazwa | Opis |
---|---|
ptr::Attach | Dołącza obiekt COM do obiektu com::ptr . |
ptr::CreateInstance | Tworzy wystąpienie obiektu COM w obiekcie com::ptr . |
ptr::Detach | Rezygnuje z własności obiektu COM, zwracając wskaźnik do obiektu. |
ptr::GetInterface | Tworzy wystąpienie obiektu COM w obiekcie com::ptr . |
ptr::QueryInterface | Wysyła zapytanie do obiektu COM należącego do interfejsu i dołącza wynik do innego com::ptr obiektu . |
ptr::Release | Zwalnia wszystkie odwołania należące do obiektu COM. |
Operatory publiczne
Nazwa | Opis |
---|---|
ptr::operator-> |
Operator dostępu do elementu członkowskiego, używany do wywoływania metod dla należącego obiektu COM. |
ptr::operator= | Dołącza obiekt COM do obiektu com::ptr . |
ptr::operator, wartość logiczna | Operator do używania com::ptr w wyrażeniu warunkowym. |
ptr::operator! | Operator określający, czy obiekt COM jest nieprawidłowy. |
Wymagania
Plik< nagłówka msclr\com\ptr.h>
Przestrzeń nazw msclr::com
ptr::p tr
Zwraca wskaźnik do należącego obiektu COM.
ptr();
ptr(
_interface_type * p
);
Parametry
P
Wskaźnik interfejsu COM.
Uwagi
Konstruktor no-argument przypisuje nullptr
do uchwytu obiektu bazowego. Przyszłe wywołania obiektu com::ptr
zweryfikują wewnętrzny obiekt i dyskretnie kończą się niepowodzeniem, dopóki obiekt nie zostanie utworzony lub dołączony.
Konstruktor jeden argument dodaje odwołanie do obiektu COM, ale nie zwalnia odwołania obiektu wywołującego, więc obiekt wywołujący musi wywołać Release
obiekt COM, aby naprawdę zrezygnować z kontroli. Po wywołaniu com::ptr
destruktora będzie automatycznie zwalniać odwołania do obiektu COM.
Przekazywanie NULL
do tego konstruktora jest takie samo, jak wywoływanie wersji no-argument.
Przykład
W tym przykładzie implementuje klasę CLR, która używa klasy com::ptr
do zawijania jej prywatnego obiektu członkowskiego IXMLDOMDocument
. Przedstawia użycie obu wersji konstruktora.
// 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
Destrukuje element com::ptr
.
~ptr();
Uwagi
W com::ptr
przypadku zniszczenia wszystkie odwołania są własnością obiektu COM. Zakładając, że nie ma żadnych innych odwołań przechowywanych do obiektu COM, obiekt COM zostanie usunięty i jego pamięć zwolniona.
Przykład
W tym przykładzie implementuje klasę CLR, która używa klasy com::ptr
do zawijania jej prywatnego obiektu członkowskiego IXMLDOMDocument
. main
W funkcji destruktory obu XmlDocument
obiektów będą wywoływane, gdy wyjdą poza zakres try
bloku, co spowoduje wywołanie destruktora bazowegocom::ptr
, zwalniając wszystkie odwołania własności do obiektu 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
Dołącza obiekt COM do obiektu com::ptr
.
void Attach(
_interface_type * _right
);
Parametry
_Prawo
Wskaźnik interfejsu COM do dołączenia.
Wyjątki
Jeśli obiekt com::ptr
COM jest już właścicielem odwołania do obiektu COM, Attach
zwraca wartość InvalidOperationException.
Uwagi
Wywołanie odwołania do Attach
obiektu COM, ale nie zwalnia odwołania obiektu wywołującego do niego.
Przekazywanie NULL
do Attach
wyników nie powoduje podjęcia żadnej akcji.
Przykład
W tym przykładzie implementuje klasę CLR, która używa klasy com::ptr
do zawijania jej prywatnego obiektu członkowskiego IXMLDOMDocument
. Funkcja składowa ReplaceDocument
najpierw wywołuje Release
dowolny wcześniej należący obiekt, a następnie wywołuje funkcję Attach
dołączania nowego obiektu dokumentu.
// 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
Tworzy wystąpienie obiektu COM w obiekcie 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
);
Parametry
progid
ProgID
Ciąg.
pouter
Wskaźnik do interfejsu IUnknown obiektu agregacji (kontrolka IUnknown). Jeśli pouter
nie zostanie określony, NULL
zostanie użyty.
cls_context
Kontekst, w którym zostanie uruchomiony kod, który zarządza nowo utworzonym obiektem. Wartości są pobierane z wyliczenia CLSCTX
. Jeśli cls_context
nie zostanie określony, zostanie użyta wartość CLSCTX_ALL.
rclsid
CLSID
skojarzone z danymi i kodem, który zostanie użyty do utworzenia obiektu.
Wyjątki
Jeśli obiekt com::ptr
jest już właścicielem odwołania do obiektu COM, CreateInstance
zgłasza wyjątek InvalidOperationException.
Ta funkcja wywołuje CoCreateInstance
funkcję i używa jej ThrowExceptionForHR do konwertowania dowolnego błędu HRESULT
na odpowiedni wyjątek.
Uwagi
CreateInstance
metoda używa CoCreateInstance
polecenia do utworzenia nowego wystąpienia określonego obiektu zidentyfikowanego na podstawie identyfikatora progID lub identyfikatora CLSID. Odwołania com::ptr
do nowo utworzonego obiektu i automatycznie zwalniają wszystkie odwołania własności podczas zniszczenia.
Przykład
W tym przykładzie zaimplementowano klasę CLR, która używa com::ptr
klasy do opakowania jej prywatnego obiektu członkowskiego IXMLDOMDocument
. Konstruktory klas używają dwóch różnych form CreateInstance
elementu , aby utworzyć obiekt dokumentu na podstawie identyfikatora ProgID lub CLSID oraz 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
Daje własność obiektu COM, zwracając wskaźnik do obiektu.
_interface_type * Detach();
Wartość zwracana
Wskaźnik do obiektu COM.
Jeśli żaden obiekt nie jest własnością, zwracana jest wartość NULL.
Wyjątki
QueryInterface
Wewnętrznie jest wywoływany na należącym do obiektu COM i każdy błąd HRESULT
jest konwertowany na wyjątek przez ThrowExceptionForHR.
Uwagi
Detach
najpierw dodaje odwołanie do obiektu COM w imieniu obiektu wywołującego, a następnie zwalnia wszystkie odwołania należące do obiektu com::ptr
. Obiekt wywołujący musi ostatecznie zwolnić zwrócony obiekt, aby go zniszczyć.
Przykład
W tym przykładzie zaimplementowano klasę CLR, która używa com::ptr
klasy do opakowania jej prywatnego obiektu członkowskiego IXMLDOMDocument
. Funkcja DetachDocument
składowa wywołuje Detach
funkcję , aby zrezygnować z własności obiektu COM i zwrócić wskaźnik do obiektu wywołującego.
// 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
Zwraca wskaźnik do należącego do niego obiektu COM.
_interface_type * GetInterface();
Wartość zwracana
Wskaźnik do należącego do obiektu COM.
Wyjątki
QueryInterface
Wewnętrznie jest wywoływany na należącym do obiektu COM i każdy błąd HRESULT
jest konwertowany na wyjątek przez ThrowExceptionForHR.
Uwagi
Obiekt com::ptr
dodaje odwołanie do obiektu COM w imieniu obiektu wywołującego, a także zachowuje własne odwołanie do obiektu COM. Obiekt wywołujący musi ostatecznie zwolnić odwołanie do zwróconego obiektu lub nigdy nie zostanie zniszczony.
Przykład
W tym przykładzie zaimplementowano klasę CLR, która używa com::ptr
klasy do opakowania jej prywatnego obiektu członkowskiego IXMLDOMDocument
. Funkcja GetDocument
składowa używa GetInterface
elementu w celu zwrócenia wskaźnika do obiektu 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
Wysyła zapytanie do obiektu COM należącego do interfejsu i dołącza wynik do innego com::ptr
obiektu .
template<class _other_type>
void QueryInterface(
ptr<_other_type> % other
);
Parametry
Innych
Spowoduje com::ptr
to uzyskanie interfejsu.
Wyjątki
QueryInterface
Wewnętrznie jest wywoływany na należącym do obiektu COM i każdy błąd HRESULT
jest konwertowany na wyjątek przez ThrowExceptionForHR.
Uwagi
Ta metoda służy do tworzenia otoki COM dla innego interfejsu obiektu COM należącego do bieżącej otoki. Ta metoda wywołuje QueryInterface
obiekt COM należącego do użytkownika, aby zażądać wskaźnika do określonego interfejsu obiektu COM i dołącza zwrócony wskaźnik interfejsu do przekazanego com::ptr
elementu .
Przykład
W tym przykładzie zaimplementowano klasę CLR, która używa com::ptr
klasy do opakowania jej prywatnego obiektu członkowskiego IXMLDOMDocument
. Funkcja WriteTopLevelNode
składowa używa QueryInterface
do wypełniania lokalnego com::ptr
za pomocą elementu IXMLDOMNode
, a następnie przekazuje com::ptr
element (przez odwołanie do śledzenia) do prywatnej funkcji składowej, która zapisuje nazwę węzła i właściwości tekstowe w konsoli.
// 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
Zwalnia wszystkie odwołania należące do obiektu COM.
void Release();
Uwagi
Wywołanie tej funkcji zwalnia wszystkie odwołania należące do obiektu COM i ustawia wewnętrzne dojście do obiektu COM na nullptr
wartość . Jeśli nie istnieją żadne inne odwołania do obiektu COM, zostanie ono zniszczone.
Przykład
W tym przykładzie zaimplementowano klasę CLR, która używa com::ptr
klasy do opakowania jej prywatnego obiektu członkowskiego IXMLDOMDocument
. Funkcja ReplaceDocument
składowa używa Release
polecenia do zwolnienia dowolnego wcześniejszego obiektu dokumentu przed dołączeniem nowego dokumentu.
// 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->
Operator dostępu do składowych używany do wywoływania metod w należącym do obiektu COM.
_detail::smart_com_ptr<_interface_type> operator->();
Wartość zwracana
Do smart_com_ptr
obiektu COM.
Wyjątki
QueryInterface
Wewnętrznie jest wywoływany na należącym do obiektu COM i każdy błąd HRESULT
jest konwertowany na wyjątek przez ThrowExceptionForHR.
Uwagi
Ten operator umożliwia wywoływanie metod należącego do obiektu COM. Zwraca tymczasowy element smart_com_ptr
, który automatycznie obsługuje własne AddRef
wartości i Release
.
Przykład
W tym przykładzie zaimplementowano klasę CLR, która używa com::ptr
klasy do opakowania jej prywatnego obiektu członkowskiego IXMLDOMDocument
. Funkcja WriteDocument
używa operator->
funkcji do wywoływania get_firstChild
elementu członkowskiego obiektu dokumentu.
// 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=
Dołącza obiekt COM do obiektu com::ptr
.
ptr<_interface_type> % operator=(
_interface_type * _right
);
Parametry
_Prawo
Wskaźnik interfejsu COM do dołączenia.
Wartość zwracana
Odwołanie do śledzenia w pliku com::ptr
.
Wyjątki
Jeśli obiekt com::ptr
jest już właścicielem odwołania do obiektu COM, operator=
zgłasza wyjątek InvalidOperationException.
Uwagi
Przypisanie obiektu COM do odwołania do com::ptr
obiektu COM, ale nie zwalnia odwołania obiektu wywołującego do niego.
Ten operator ma taki sam efekt jak Attach
.
Przykład
W tym przykładzie zaimplementowano klasę CLR, która używa com::ptr
klasy do opakowania jej prywatnego obiektu członkowskiego IXMLDOMDocument
. Funkcja ReplaceDocument
składowa najpierw wywołuje Release
dowolny wcześniej należący obiekt, a następnie używa operator=
go do dołączenia nowego obiektu dokumentu.
// 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, wartość logiczna
Operator do użycia com::ptr
w wyrażeniu warunkowym.
operator bool();
Wartość zwracana
true
jeśli posiadany obiekt COM jest prawidłowy; false
Inaczej.
Uwagi
Obiekt COM jest prawidłowy, jeśli nie nullptr
jest .
Ten operator konwertuje na element, który _detail_class::_safe_bool
jest bezpieczniejszy niż bool
, ponieważ nie można przekonwertować go na typ całkowity.
Przykład
W tym przykładzie zaimplementowano klasę CLR, która używa com::ptr
klasy do opakowania jej prywatnego obiektu członkowskiego IXMLDOMDocument
. Funkcja CreateInstance
składowa jest używana operator bool
po utworzeniu nowego obiektu dokumentu w celu określenia, czy jest on prawidłowy i czy jest on zapisywany w konsoli programu .
// 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!
Operator określający, czy należący do niego obiekt COM jest nieprawidłowy.
bool operator!();
Wartość zwracana
true
jeśli należący do obiektu COM jest nieprawidłowy; false
Inaczej.
Uwagi
Obiekt COM jest prawidłowy, jeśli nie nullptr
jest .
Przykład
W tym przykładzie implementuje klasę CLR, która używa klasy com::ptr
do zawijania jej prywatnego obiektu członkowskiego IXMLDOMDocument
. Funkcja CreateInstance
składowa używa funkcji operator!
do określenia, czy obiekt dokumentu jest już własnością, i tworzy tylko nowe wystąpienie, jeśli obiekt jest nieprawidłowy.
// 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.