com::ptr – třída
Obálka objektu COM, který lze použít jako člen třídy CLR. Obálka také automatizuje správu životnosti objektu COM a při zavolání jeho destruktoru uvolní všechny vlastněné odkazy na objekt. Obdobou třídy CComPtr.
Syntaxe
template<class _interface_type>
ref class ptr;
Parametry
_interface_type
Rozhraní MODELU COM.
Poznámky
A com::ptr
lze také použít jako místní proměnnou funkce pro zjednodušení různých úloh modelu COM a automatizaci správy životnosti.
A com::ptr
nelze použít přímo jako parametr funkce; místo toho použijte operátor reference sledování nebo operátor Popisovač objektu (^).
Objekt com::ptr
nelze přímo vrátit z funkce; místo toho použijte popisovač.
Příklad
Tento příklad implementuje třídu CLR, která používá k zabalení objektu com::ptr
soukromého člena IXMLDOMDocument
. Volání veřejných metod třídy má za následek volání obsaženého IXMLDOMDocument
objektu. Ukázka vytvoří instanci dokumentu XML, vyplní ji jednoduchým kódem XML a provede zjednodušenou procházku po uzlech v analyzované stromové struktuře dokumentu, aby se kód XML vytiskl do konzoly.
// 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>
Členové
Veřejné konstruktory
Název | Description |
---|---|
ptr::p tr | Vytvoří objekt com::ptr pro zabalení objektu COM. |
ptr::~ptr | Destrukuje .com::ptr |
Veřejné metody
Název | Description |
---|---|
ptr::Attach | Připojí objekt COM k objektu com::ptr . |
ptr::CreateInstance | Vytvoří instanci objektu COM v rámci objektu com::ptr . |
ptr::Detach | Zahodí vlastnictví objektu COM a vrátí ukazatel na objekt. |
ptr::GetInterface | Vytvoří instanci objektu COM v rámci objektu com::ptr . |
ptr::QueryInterface | Dotazuje vlastněný objekt COM na rozhraní a připojí výsledek k jinému com::ptr objektu . |
ptr::Release | Uvolní všechny vlastněné odkazy na objekt COM. |
Veřejné operátory
Název | Description |
---|---|
ptr::operator-> |
Operátor přístupu člena, který se používá k volání metod na vlastněný objekt COM. |
ptr::operator= | Připojí objekt COM k objektu com::ptr . |
ptr::operator bool | Operátor pro použití com::ptr v podmíněném výrazu |
ptr::operator! | Operátor určující, zda je vlastněný objekt COM neplatný. |
Požadavky
Hlavičkový soubor< msclr\com\ptr.h>
Obor názvů msclr::com
ptr::p tr
Vrátí ukazatel na vlastněný objekt COM.
ptr();
ptr(
_interface_type * p
);
Parametry
P
Ukazatel rozhraní COM.
Poznámky
Konstruktor bez argumentu nullptr
se přiřadí k podkladovému popisovači objektu. Budoucí volání objektu com::ptr
ověří interní objekt a bezobslužně selžou, dokud objekt není vytvořen nebo připojen.
Konstruktor s jedním argumentem přidá odkaz na objekt COM, ale neuvolní odkaz na volajícího, takže volající musí volat Release
objekt COM, aby se skutečně vzdal řízení. com::ptr
Když je destruktor volána, automaticky uvolní své odkazy na objekt COM.
Předání NULL
do tohoto konstruktoru je stejné jako volání verze bez argumentu.
Příklad
Tento příklad implementuje třídu CLR, která používá k zabalení objektu com::ptr
soukromého člena IXMLDOMDocument
. Ukazuje použití obou verzí konstruktoru.
// 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 .com::ptr
~ptr();
Poznámky
Při zničení com::ptr
všechny vydané verze odkazují na jeho objekt COM. Za předpokladu, že na objekt COM neexistují žádné další odkazy, bude objekt COM odstraněn a jeho paměť se uvolní.
Příklad
Tento příklad implementuje třídu CLR, která používá k zabalení objektu com::ptr
soukromého člena IXMLDOMDocument
. main
Ve funkci budou volány destruktory dvou XmlDocument
objektů, když se dostanou mimo rozsah try
bloku, což vede k zavolání základního com::ptr
destruktoru, který uvolní všechny vlastněné odkazy na objekt 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
Připojí objekt COM k objektu com::ptr
.
void Attach(
_interface_type * _right
);
Parametry
_Právo
Ukazatel rozhraní MODELU COM pro připojení.
Výjimky
com::ptr
Pokud již vlastní odkaz na objekt COM, Attach
vyvolá InvalidOperationException.
Poznámky
Volání odkazuje Attach
na objekt COM, ale neuvolní odkaz volajícího na něj.
Předání NULL
do Attach
způsobí, že se neprovedou žádné akce.
Příklad
Tento příklad implementuje třídu CLR, která používá k zabalení objektu com::ptr
soukromého člena IXMLDOMDocument
. Členské ReplaceDocument
funkce nejprve zavolá Release
libovolný objekt, který dříve vlastní, a pak zavolá k Attach
připojení nového objektu 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
Vytvoří instanci objektu COM v rámci objektu 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
Řetězec ProgID
.
pouter
Ukazatel na rozhraní IUnknown agregovaného objektu (řídicí IUnknown). Pokud pouter
není zadaný, NULL
použije se .
cls_context
Kontext, ve kterém se spustí kód, který spravuje nově vytvořený objekt. Hodnoty jsou převzaty z výčtu CLSCTX
. Pokud cls_context
není zadaný, použije se hodnota CLSCTX_ALL.
identifikátor rclsid
CLSID
přidružené k datům a kódu, které budou použity k vytvoření objektu.
Výjimky
com::ptr
Pokud již vlastní odkaz na objekt COM, CreateInstance
vyvolá InvalidOperationException.
Tato funkce volá CoCreateInstance
a používá ThrowExceptionForHR k převodu všech chyb HRESULT
na příslušnou výjimku.
Poznámky
CreateInstance
používá CoCreateInstance
k vytvoření nové instance zadaného objektu identifikovaného buď z Identifikátoru ProgID, nebo CLSID. Odkazuje com::ptr
na nově vytvořený objekt a při zničení automaticky uvolní všechny vlastněné odkazy.
Příklad
Tento příklad implementuje třídu CLR, která používá k zabalení objektu com::ptr
soukromého člena IXMLDOMDocument
. Konstruktory třídy používají dvě různé formy CreateInstance
k vytvoření objektu dokumentu buď z Identifikátoru ProgID, nebo z CLSID plus 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
Zahodí vlastnictví objektu COM a vrátí ukazatel na objekt.
_interface_type * Detach();
Vrácená hodnota
Ukazatel na objekt COM.
Pokud není objekt vlastněný, vrátí se hodnota NULL.
Výjimky
Interně QueryInterface
se volá na vlastněný objekt COM a všechny chyby HRESULT
jsou převedeny na výjimku pomocí ThrowExceptionForHR.
Poznámky
Detach
nejprve přidá odkaz na objekt COM jménem volajícího a pak uvolní všechny odkazy vlastněné objektem com::ptr
. Volající musí nakonec uvolnit vrácený objekt, aby ho zničil.
Příklad
Tento příklad implementuje třídu CLR, která používá k zabalení objektu com::ptr
soukromého člena IXMLDOMDocument
. Volání DetachDocument
členské funkce Detach
, aby se vzdala vlastnictví objektu COM a vrátila ukazatel na volajícího.
// 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
Vrátí ukazatel na vlastněný objekt COM.
_interface_type * GetInterface();
Vrácená hodnota
Ukazatel na vlastněný objekt COM.
Výjimky
Interně QueryInterface
se volá na vlastněný objekt COM a všechny chyby HRESULT
jsou převedeny na výjimku pomocí ThrowExceptionForHR.
Poznámky
Objekt com::ptr
přidá odkaz na objekt COM jménem volajícího a také zachová vlastní odkaz na objekt COM. Volající musí nakonec uvolnit odkaz na vrácený objekt, jinak nebude nikdy zničen.
Příklad
Tento příklad implementuje třídu CLR, která používá k zabalení objektu com::ptr
soukromého člena IXMLDOMDocument
. Členské GetDocument
funkce používá GetInterface
k vrácení ukazatele na objekt 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
Dotazuje vlastněný objekt COM na rozhraní a připojí výsledek k jinému com::ptr
objektu .
template<class _other_type>
void QueryInterface(
ptr<_other_type> % other
);
Parametry
Další
Ten com::ptr
získá rozhraní.
Výjimky
Interně QueryInterface
se volá na vlastněný objekt COM a všechny chyby HRESULT
jsou převedeny na výjimku pomocí ThrowExceptionForHR.
Poznámky
Tuto metodu použijte k vytvoření obálky MODELU COM pro jiné rozhraní objektu COM vlastněného aktuální obálkou. Tato metoda volá QueryInterface
prostřednictvím vlastněného objektu COM k vyžádání ukazatele na konkrétní rozhraní objektu COM a připojí vrácený ukazatel rozhraní k předané com::ptr
.
Příklad
Tento příklad implementuje třídu CLR, která používá k zabalení objektu com::ptr
soukromého člena IXMLDOMDocument
. Členská WriteTopLevelNode
funkce použije QueryInterface
k vyplnění místního com::ptr
IXMLDOMNode
objektu an a pak předá com::ptr
(pomocí odkazu sledování) do soukromé členské funkce, která do konzoly zapíše název uzlu a textové vlastnosti.
// 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
Uvolní všechny vlastněné odkazy na objekt COM.
void Release();
Poznámky
Volání této funkce uvolní všechny vlastněné odkazy na objekt COM a nastaví interní popisovač objektu COM na nullptr
. Pokud neexistují žádné jiné odkazy na objekt COM, bude zničen.
Příklad
Tento příklad implementuje třídu CLR, která používá k zabalení objektu com::ptr
soukromého člena IXMLDOMDocument
. Člen funkce ReplaceDocument
používá Release
k uvolnění jakéhokoli předchozího objektu dokumentu před připojením nového 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->
Operátor přístupu člena, který se používá k volání metod na vlastněný objekt COM.
_detail::smart_com_ptr<_interface_type> operator->();
Vrácená hodnota
A smart_com_ptr
do objektu COM.
Výjimky
Interně QueryInterface
se volá na vlastněný objekt COM a všechny chyby HRESULT
jsou převedeny na výjimku pomocí ThrowExceptionForHR.
Poznámky
Tento operátor umožňuje volat metody vlastněného objektu COM. Vrátí dočasné smart_com_ptr
, které automaticky zpracovává své vlastní AddRef
a Release
.
Příklad
Tento příklad implementuje třídu CLR, která používá k zabalení objektu com::ptr
soukromého člena IXMLDOMDocument
. Funkce WriteDocument
používá operator->
k volání člena get_firstChild
objektu 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=
Připojí objekt COM k objektu com::ptr
.
ptr<_interface_type> % operator=(
_interface_type * _right
);
Parametry
_Právo
Ukazatel rozhraní MODELU COM pro připojení.
Vrácená hodnota
Referenční informace o sledování na com::ptr
.
Výjimky
com::ptr
Pokud již vlastní odkaz na objekt COM, operator=
vyvolá InvalidOperationException.
Poznámky
Přiřazení objektu COM k objektu com::ptr
odkazuje na objekt COM, ale neuvolní odkaz volajícího na něj.
Tento operátor má stejný účinek jako Attach
.
Příklad
Tento příklad implementuje třídu CLR, která používá k zabalení objektu com::ptr
soukromého člena IXMLDOMDocument
. Člen funkce ReplaceDocument
nejprve zavolá Release
u libovolného objektu, který dříve vlastnil, a pak použije operator=
k připojení nového objektu 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 bool
Operátor pro použití com::ptr
v podmíněném výrazu
operator bool();
Vrácená hodnota
true
je-li vlastněný objekt COM platný; false
Jinak.
Poznámky
Vlastněný objekt COM je platný, pokud není nullptr
.
Tento operátor převede na _detail_class::_safe_bool
operátor, který je bezpečnější než bool
proto, že ho nelze převést na celočíselný typ.
Příklad
Tento příklad implementuje třídu CLR, která používá k zabalení objektu com::ptr
soukromého člena IXMLDOMDocument
. Členská CreateInstance
funkce použije operator bool
po vytvoření nového objektu dokumentu k určení, jestli je objekt platný, a pokud ano, zapíše do konzoly.
// 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!
Operátor určující, zda je vlastněný objekt COM neplatný.
bool operator!();
Vrácená hodnota
true
je-li vlastněný objekt COM neplatný; false
Jinak.
Poznámky
Vlastněný objekt COM je platný, pokud není nullptr
.
Příklad
Tento příklad implementuje třídu CLR, která používá k zabalení objektu com::ptr
soukromého člena IXMLDOMDocument
. Členské CreateInstance
funkce používá operator!
k určení, jestli je objekt dokumentu již vlastněný, a vytvoří novou instanci pouze v případě, že je objekt neplatný.
// 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.