com::ptr-Klasse
Ein Wrapper für ein COM-Objekt, das als Member einer CLR-Klasse verwendet werden kann. Der Wrapper automatisiert auch die Lebensdauerverwaltung des COM-Objekts und gibt alle eigenen Verweise auf das Objekt frei, wenn sein Destruktor aufgerufen wird. Analog zur CComPtr-Klasse.
Syntax
template<class _interface_type>
ref class ptr;
Parameter
_interface_type
COM-Schnittstelle.
Hinweise
Kann com::ptr
auch als lokale Funktionsvariable verwendet werden, um verschiedene COM-Aufgaben zu vereinfachen und die Lebensdauerverwaltung zu automatisieren.
Kann com::ptr
nicht direkt als Funktionsparameter verwendet werden. Verwenden Sie stattdessen einen Nachverfolgungsverweisoperator oder einen Handle-to-Object-Operator (^).
Kann com::ptr
nicht direkt von einer Funktion zurückgegeben werden. Verwenden Sie stattdessen ein Handle.
Beispiel
In diesem Beispiel wird eine CLR-Klasse implementiert, die ein com::ptr
verwendet, um das private Memberobjekt IXMLDOMDocument
zu umschließen. Das Aufrufen der öffentlichen Methoden der -Klasse führt zu Aufrufen des enthaltenen IXMLDOMDocument
Objekts. Das Beispiel erstellt eine Instanz eines XML-Dokuments, füllt es mit einfachem XML auf und führt einen vereinfachten Überblick über die Knoten in der analysierten Dokumentstruktur durch, um den XML-Code in der Konsole auszudrucken.
// 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>
Member
Öffentliche Konstruktoren
Name | BESCHREIBUNG |
---|---|
ptr::ptr | Erstellt eine com::ptr , um ein COM-Objekt zu umschließen. |
ptr::~ptr | Zerstört eine com::ptr . |
Öffentliche Methoden
Name | BESCHREIBUNG |
---|---|
ptr::Attach | Fügt ein COM-Objekt an eine com::ptr an. |
ptr::CreateInstance | Erstellt eine Instanz eines COM-Objekts in einem com::ptr . |
ptr::Detach | Gibt den Besitz des COM-Objekts auf und gibt einen Zeiger auf das -Objekt zurück. |
ptr::GetInterface | Erstellt eine Instanz eines COM-Objekts in einem com::ptr . |
ptr::QueryInterface | Fragt das eigene COM-Objekt nach einer Schnittstelle ab und fügt das Ergebnis an eine andere com::ptr an. |
ptr::Release | Gibt alle eigenen Verweise auf das COM-Objekt frei. |
Öffentliche Operatoren
Name | BESCHREIBUNG |
---|---|
ptr::operator-> |
Memberzugriffsoperator, der zum Aufrufen von Methoden für das eigene COM-Objekt verwendet wird. |
ptr::operator= | Fügt ein COM-Objekt an eine com::ptr an. |
ptr::operator bool | Operator für die Verwendung com::ptr in einem bedingten Ausdruck. |
ptr::operator! | Operator, um zu bestimmen, ob das com-Objekt im Besitz ungültig ist. |
Anforderungen
Headerdatei< msclr\com\ptr.h>
Namespace msclr::com
ptr::ptr
Gibt einen Zeiger auf das eigene COM-Objekt zurück.
ptr();
ptr(
_interface_type * p
);
Parameter
P
Ein COM-Schnittstellenzeiger.
Hinweise
Der No-Argument-Konstruktor weist nullptr
dem zugrunde liegenden Objekthandle zu. Zukünftige Aufrufe von com::ptr
überprüfen das interne Objekt und schlagen automatisch fehl, bis ein Objekt erstellt oder angefügt wird.
Der Konstruktor mit einem Argument fügt einen Verweis auf das COM-Objekt hinzu, gibt jedoch den Verweis des Aufrufers nicht frei, sodass der Aufrufer für das COM-Objekt aufrufen Release
muss, um die Steuerung wirklich aufzugeben. Wenn der com::ptr
Destruktor von aufgerufen wird, gibt er automatisch seine Verweise auf das COM-Objekt frei.
Die Übergabe NULL
an diesen Konstruktor entspricht dem Aufrufen der No-Argument-Version.
Beispiel
In diesem Beispiel wird eine CLR-Klasse implementiert, die ein com::ptr
verwendet, um das private Memberobjekt IXMLDOMDocument
zu umschließen. Es veranschaulicht die Verwendung beider Versionen des Konstruktors.
// 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
Zerstört eine com::ptr
.
~ptr();
Hinweise
Bei der com::ptr
Zerstörung gibt alle Verweise auf sein COM-Objekt frei, die es besitzt. Unter der Annahme, dass keine anderen Verweise auf das COM-Objekt vorhanden sind, wird das COM-Objekt gelöscht und sein Arbeitsspeicher freigegeben.
Beispiel
In diesem Beispiel wird eine CLR-Klasse implementiert, die ein com::ptr
verwendet, um das private Memberobjekt IXMLDOMDocument
zu umschließen. In der main
-Funktion werden die Destruktoren der beiden XmlDocument
Objekte aufgerufen, wenn sie den Bereich des try
-Blocks sprengen. Dies führt dazu, dass der zugrunde liegende com::ptr
Destruktor aufgerufen wird und alle eigenen Verweise auf das COM-Objekt freigegeben werden.
// 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
Fügt ein COM-Objekt an eine com::ptr
an.
void Attach(
_interface_type * _right
);
Parameter
_right
Der anzufügende COM-Schnittstellenzeiger.
Ausnahmen
Wenn der com::ptr
bereits einen Verweis auf ein COM-Objekt besitzt, Attach
löst aus InvalidOperationException.
Hinweise
Ein Aufruf von Attach
verweist auf das COM-Objekt, gibt jedoch den Verweis des Aufrufers darauf nicht frei.
Die Übergabe NULL
an führt dazu, Attach
dass keine Aktion ausgeführt wird.
Beispiel
In diesem Beispiel wird eine CLR-Klasse implementiert, die ein com::ptr
verwendet, um das private Memberobjekt IXMLDOMDocument
zu umschließen. Die ReplaceDocument
Memberfunktion ruft Release
zuerst für jedes zuvor im Besitz befindliche Objekt auf und ruft dann auf Attach
, um ein neues Dokumentobjekt anzufügen.
// 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
Erstellt eine Instanz eines COM-Objekts in einem 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
);
Parameter
Progid
Eine ProgID
-Zeichenfolge.
1000000
Zeiger auf die IUnknown-Schnittstelle des Aggregatobjekts (die steuernde IUnknown). Wenn pouter
nicht angegeben ist, NULL
wird verwendet.
cls_context
Kontext, in dem der Code, der das neu erstellte Objekt verwaltet, ausgeführt wird. Die Werte stammen aus der CLSCTX
-Enumeration. Wenn cls_context
nicht angegeben ist, wird der CLSCTX_ALL verwendet.
rclsid
CLSID
wird den Daten und dem Code zugeordnet, die zum Erstellen des Objekts verwendet werden.
Ausnahmen
Wenn der com::ptr
bereits einen Verweis auf ein COM-Objekt besitzt, löst CreateInstance
aus InvalidOperationException.
Diese Funktion ruft auf CoCreateInstance
und verwendet , ThrowExceptionForHR um jeden Fehler in eine HRESULT
entsprechende Ausnahme zu konvertieren.
Hinweise
CreateInstance
verwendet CoCreateInstance
, um eine neue Instanz des angegebenen Objekts zu erstellen, die entweder aus einer ProgID oder einer CLSID identifiziert wird. verweist com::ptr
auf das neu erstellte Objekt und gibt bei der Zerstörung automatisch alle eigenen Verweise frei.
Beispiel
In diesem Beispiel wird eine CLR-Klasse implementiert, die ein verwendet com::ptr
, um sein privates Memberobjekt zu IXMLDOMDocument
umschließen. Die Klassenkonstruktoren verwenden zwei verschiedene CreateInstance
Formen von , um das Dokumentobjekt entweder aus einer ProgID oder einer CLSID plus einer CLSCTX zu erstellen.
// 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
Gibt den Besitz des COM-Objekts auf und gibt einen Zeiger auf das -Objekt zurück.
_interface_type * Detach();
Rückgabewert
Der Zeiger auf das COM-Objekt.
Wenn kein Objekt im Besitz von ist, wird NULL zurückgegeben.
Ausnahmen
Intern wird für QueryInterface
das eigene COM-Objekt aufgerufen, und jeder HRESULT
Fehler wird von in eine Ausnahme konvertiert ThrowExceptionForHR.
Hinweise
Detach
fügt zunächst im Namen des Aufrufers einen Verweis auf das COM-Objekt hinzu und gibt dann alle Verweise frei, die sich im Besitz von befinden com::ptr
. Der Aufrufer muss letztendlich das zurückgegebene Objekt frei geben, um es zu zerstören.
Beispiel
In diesem Beispiel wird eine CLR-Klasse implementiert, die ein verwendet com::ptr
, um sein privates Memberobjekt zu IXMLDOMDocument
umschließen. Die DetachDocument
Memberfunktion ruft auf Detach
, um den Besitz des COM-Objekts zu übernehmen und einen Zeiger auf den Aufrufer zurück zu geben.
// 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
Gibt einen Zeiger auf das eigene COM-Objekt zurück.
_interface_type * GetInterface();
Rückgabewert
Ein Zeiger auf das eigene COM-Objekt.
Ausnahmen
Intern wird für QueryInterface
das eigene COM-Objekt aufgerufen, und jeder HRESULT
Fehler wird von in eine Ausnahme konvertiert ThrowExceptionForHR.
Hinweise
fügt com::ptr
einen Verweis auf das COM-Objekt im Namen des Aufrufers hinzu und behält auch seinen eigenen Verweis auf das COM-Objekt bei. Der Aufrufer muss letztendlich den Verweis auf das zurückgegebene Objekt veröffentlichen, da er nicht zerstört wird.
Beispiel
In diesem Beispiel wird eine CLR-Klasse implementiert, die ein verwendet com::ptr
, um sein privates Memberobjekt zu IXMLDOMDocument
umschließen. Die GetDocument
Memberfunktion verwendet , GetInterface
um einen Zeiger auf das COM-Objekt zurück zu geben.
// 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
Fragt das eigene COM-Objekt nach einer Schnittstelle ab und hängt das Ergebnis an eine andere an com::ptr
.
template<class _other_type>
void QueryInterface(
ptr<_other_type> % other
);
Parameter
Andere
Die com::ptr
, die die Schnittstelle erhalten wird.
Ausnahmen
Intern wird für QueryInterface
das eigene COM-Objekt aufgerufen, und jeder HRESULT
Fehler wird von in eine Ausnahme konvertiert ThrowExceptionForHR.
Hinweise
Verwenden Sie diese Methode, um einen COM-Wrapper für eine andere Schnittstelle des COM-Objekts zu erstellen, das sich im Besitz des aktuellen Wrappers befindet. Diese Methode ruft über QueryInterface
das eigene COM-Objekt auf, um einen Zeiger auf eine bestimmte Schnittstelle des COM-Objekts an fordern, und angefügt den zurückgegebenen Schnittstellenzeiger an den übergebenen com::ptr
.
Beispiel
In diesem Beispiel wird eine CLR-Klasse implementiert, die ein verwendet com::ptr
, um sein privates Memberobjekt zu IXMLDOMDocument
umschließen. Die WriteTopLevelNode
Memberfunktion verwendet , IXMLDOMNode
QueryInterface
com::ptr
com::ptr
um ein lokales mit einem zu füllen, und übergibt dann (durch Nachverfolgungsverweis) an eine private Memberfunktion, die die Namens- und Texteigenschaften des Knotens in die Konsole schreibt.
// 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
Gibt alle verweise im Besitz des COM-Objekts frei.
void Release();
Hinweise
Durch Aufrufen dieser Funktion werden alle eigenen Verweise auf das COM-Objekt und das interne Handle für das COM-Objekt auf veröffentlicht nullptr
. Wenn keine anderen Verweise auf das COM-Objekt vorhanden sind, wird es zerstört.
Beispiel
In diesem Beispiel wird eine CLR-Klasse implementiert, die ein verwendet com::ptr
, um sein privates Memberobjekt zu IXMLDOMDocument
umschließen. Die ReplaceDocument
Memberfunktion verwendet , Release
um alle vorherigen Dokumentobjekten frei zu geben, bevor das neue Dokument angefügt wird.
// 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->
Memberzugriffsoperator, der zum Aufrufen von Methoden für das eigene COM-Objekt verwendet wird.
_detail::smart_com_ptr<_interface_type> operator->();
Rückgabewert
Ein smart_com_ptr
für das COM-Objekt.
Ausnahmen
Intern wird für QueryInterface
das eigene COM-Objekt aufgerufen, und jeder HRESULT
Fehler wird von in eine Ausnahme konvertiert ThrowExceptionForHR.
Hinweise
Mit diesem Operator können Sie Methoden des eigenen COM-Objekts aufrufen. Es wird ein temporäres zurückgegeben smart_com_ptr
, das automatisch seine eigenen und behandelt AddRef
Release
.
Beispiel
In diesem Beispiel wird eine CLR-Klasse implementiert, die ein verwendet com::ptr
, um sein privates Memberobjekt zu IXMLDOMDocument
umschließen. Die WriteDocument
Funktion verwendet , operator->
um den Member get_firstChild
des Dokumentobjekts auf aufruft.
// 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=
Angefügt ein COM-Objekt an eine com::ptr
.
ptr<_interface_type> % operator=(
_interface_type * _right
);
Parameter
_right
Der com-Schnittstellenzeiger, der angefügt werden soll.
Rückgabewert
Ein Nachverfolgungsverweis auf .com::ptr
Ausnahmen
Wenn der com::ptr
bereits einen Verweis auf ein COM-Objekt besitzt, löst operator=
aus InvalidOperationException.
Hinweise
Das Zuweisen eines COM-Objekts zu einem com::ptr
verweist auf das COM-Objekt, gibt jedoch nicht den Verweis des Aufrufers darauf frei.
Dieser Operator hat die gleiche Wirkung wie Attach
.
Beispiel
In diesem Beispiel wird eine CLR-Klasse implementiert, die ein verwendet com::ptr
, um sein privates Memberobjekt zu IXMLDOMDocument
umschließen. Die ReplaceDocument
Memberfunktion ruft zuerst für alle Release
zuvor im Besitz befindlichen Objekte auf und verwendet dann , operator=
um ein neues Dokumentobjekt anfügen.
// 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
Operator für die Verwendung com::ptr
in einem bedingten Ausdruck.
operator bool();
Rückgabewert
true
, wenn das eigene COM-Objekt gültig ist; false
Andernfalls.
Hinweise
Das eigene COM-Objekt ist gültig, wenn es nicht ist nullptr
.
Dieser Operator konvertiert in , was _detail_class::_safe_bool
sicherer als ist bool
, da er nicht in einen integralen Typ konvertiert werden kann.
Beispiel
In diesem Beispiel wird eine CLR-Klasse implementiert, die ein verwendet com::ptr
, um sein privates Memberobjekt zu IXMLDOMDocument
umschließen. Die CreateInstance
Memberfunktion verwendet nach dem operator bool
Erstellen des neuen Dokumentobjekts, um zu bestimmen, ob es gültig ist, und schreibt in die Konsole, wenn dies der Ist.
// 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, um zu bestimmen, ob das eigene COM-Objekt ungültig ist.
bool operator!();
Rückgabewert
true
, wenn das eigene COM-Objekt ungültig ist; false
Andernfalls.
Hinweise
Das eigene COM-Objekt ist gültig, wenn es nicht ist nullptr
.
Beispiel
In diesem Beispiel wird eine CLR-Klasse implementiert, die ein com::ptr
verwendet, um das private Memberobjekt IXMLDOMDocument
zu umschließen. Die CreateInstance
Memberfunktion verwendet , operator!
um zu bestimmen, ob ein Dokumentobjekt bereits im Besitz ist, und erstellt nur dann eine neue -Instanz, wenn das Objekt ungültig ist.
// 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.