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 uvolní všechny vlastněné odkazy na objekt, když je volána jeho destruktor. Analogické s CComPtr třída.
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 ke zjednodušení různých úloh modelu COM a automatizaci správy životnosti.
Nelze com::ptr
použít přímo jako parametr funkce. Místo toho použijte operátor sledovacího odkazu nebo popisovač k operátoru objektu (^).
Funkci com::ptr
nelze vrátit přímo. Místo toho použijte popisovač.
Příklad
Tento příklad implementuje třídu CLR, která používá com::ptr
k zabalení jeho objektu soukromého člena IXMLDOMDocument
. Volání veřejných metod třídy vede k volání obsaženého IXMLDOMDocument
objektu. Ukázka vytvoří instanci dokumentu XML, vyplní ho jednoduchým kódem XML a provede zjednodušenou procházku uzlů ve stromu analyzovaných dokumentů a vytiskne XML 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
Jméno | popis |
---|---|
ptr::ptr | Vytvoří objekt com::ptr COM pro zabalení objektu. |
ptr::~ptr | Destrukce a com::ptr . |
Veřejné metody
Jméno | popis |
---|---|
ptr::Attach | Připojí objekt COM k objektu com::ptr . |
ptr::CreateInstance | Vytvoří instanci objektu COM v rámci objektu com::ptr . |
ptr::Detach | Dává vlastnictví objektu COM a vrací ukazatel na objekt. |
ptr::GetInterface | Vytvoří instanci objektu COM v rámci objektu com::ptr . |
ptr::QueryInterface | Dotazuje vlastněný objekt COM pro rozhraní a připojí výsledek k jinému com::ptr . |
ptr::Release | Uvolní všechny vlastněné odkazy na objekt COM. |
Veřejné operátory
Jméno | popis |
---|---|
ptr::operator-> |
Operátor přístupu člena, který se používá k volání metod ve vlastnictví objektu 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::ptr
Vrátí ukazatel na vlastněný objekt COM.
ptr();
ptr(
_interface_type * p
);
Parametry
P
Ukazatel rozhraní MODELU COM.
Poznámky
Konstruktor bez argumentu nullptr
přiřadí podkladovému popisovači objektu. Budoucí volání do objektu com::ptr
ověří vnitřní objekt a bezobslužně selžou, dokud se objekt nevytvořil nebo připojí.
Konstruktor s jedním argumentem přidá odkaz na objekt COM, ale neuvolní odkaz volajícího, takže volající musí volat Release
objekt COM, aby 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á com::ptr
k zabalení jeho objektu 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
Destrukce a com::ptr
.
~ptr();
Poznámky
Při zničení uvolní com::ptr
všechny odkazy, které vlastní na jeho objekt COM. Za předpokladu, že neexistují žádné další odkazy na objekt COM, objekt COM bude odstraněn a jeho paměť uvolněna.
Příklad
Tento příklad implementuje třídu CLR, která používá com::ptr
k zabalení jeho objektu soukromého člena IXMLDOMDocument
. main
Ve funkci budou dva XmlDocument
objekty destruktory volány, když vyjdou z rozsahu try
bloku, což vede k tomu, že se volá základní com::ptr
destruktor a 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, který se má připojit.
Výjimky
com::ptr
Pokud již vlastní odkaz na objekt COM, Attach
vyvolá InvalidOperationException.
Poznámky
Volání Attach
odkazuje na objekt COM, ale neuvolní odkaz volajícího na něj.
Attach
Předání NULL
výsledkům způsobí, že se neprovedou žádné akce.
Příklad
Tento příklad implementuje třídu CLR, která používá com::ptr
k zabalení jeho objektu soukromého člena IXMLDOMDocument
. Členské ReplaceDocument
funkce nejprve volá Release
jakýkoli dříve vlastněný objekt a potom volání Attach
pro 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í zadáno, 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í zadán, použije se hodnota, CLSCTX_ALL.
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 jakékoli chyby HRESULT
na příslušnou výjimku.
Poznámky
CreateInstance
používá CoCreateInstance
k vytvoření nové instance zadaného objektu identifikovaného z ProgID nebo CLSID. Odkazy com::ptr
na nově vytvořený objekt a automaticky uvolní všechny vlastněné odkazy při zničení.
Příklad
Tento příklad implementuje třídu CLR, která používá com::ptr
k zabalení jeho objektu soukromého člena IXMLDOMDocument
. Konstruktory třídy používají dvě různé formy CreateInstance
k vytvoření objektu dokumentu buď z 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
Dává vlastnictví objektu COM a vrací ukazatel na objekt.
_interface_type * Detach();
Vrácená hodnota
Ukazatel na objekt COM.
Pokud žádný objekt nevlastní, vrátí se hodnota NULL.
Výjimky
Interně je QueryInterface
volána ve vlastnictví objektu COM a všechny chyby HRESULT
jsou převedeny na výjimku .ThrowExceptionForHR
Poznámky
Detach
nejprve přidá odkaz na objekt COM jménem volajícího a poté 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á com::ptr
k zabalení jeho objektu soukromého člena IXMLDOMDocument
. Členské DetachDocument
funkce volá Detach
, aby 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ě je QueryInterface
volána ve vlastnictví objektu COM a všechny chyby HRESULT
jsou převedeny na výjimku .ThrowExceptionForHR
Poznámky
Přidá com::ptr
odkaz na objekt COM jménem volajícího a také uchovává vlastní odkaz na objekt COM. Volající musí nakonec uvolnit odkaz na vrácený objekt, nebo nebude nikdy zničen.
Příklad
Tento příklad implementuje třídu CLR, která používá com::ptr
k zabalení jeho objektu soukromého člena IXMLDOMDocument
. Členová 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 pro rozhraní a připojí výsledek k jinému com::ptr
.
template<class _other_type>
void QueryInterface(
ptr<_other_type> % other
);
Parametry
Další
Tím com::ptr
se rozhraní získá.
Výjimky
Interně je QueryInterface
volána ve vlastnictví objektu COM a všechny chyby HRESULT
jsou převedeny na výjimku .ThrowExceptionForHR
Poznámky
Tato metoda slouží k vytvoření obálky MODELU COM pro jiné rozhraní objektu COM vlastněného aktuálním obálkou. Tato metoda volá QueryInterface
prostřednictvím vlastněného objektu COM požadovat ukazatel na konkrétní rozhraní objektu COM a připojí vrácený ukazatel rozhraní předaný com::ptr
.
Příklad
Tento příklad implementuje třídu CLR, která používá com::ptr
k zabalení jeho objektu soukromého člena IXMLDOMDocument
. Členská WriteTopLevelNode
funkce používá QueryInterface
k vyplnění místního objektu com::ptr
IXMLDOMNode
a následnému předá com::ptr
(pomocí odkazu na sledování) privátní členské funkci, která zapisuje název uzlu a vlastnosti textu do konzoly.
// 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é další odkazy na objekt COM, bude zničen.
Příklad
Tento příklad implementuje třídu CLR, která používá com::ptr
k zabalení jeho objektu soukromého člena IXMLDOMDocument
. Členské ReplaceDocument
funkce 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 ve vlastnictví objektu COM.
_detail::smart_com_ptr<_interface_type> operator->();
Vrácená hodnota
A smart_com_ptr
k objektu COM.
Výjimky
Interně je QueryInterface
volána ve vlastnictví objektu COM a všechny chyby HRESULT
jsou převedeny na výjimku .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á com::ptr
k zabalení jeho objektu soukromého člena IXMLDOMDocument
. Funkce WriteDocument
používá operator->
k volání get_firstChild
člena 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, který se má připojit.
Vrácená hodnota
Sledování odkazu na com::ptr
.
Výjimky
com::ptr
Pokud již vlastní odkaz na objekt COM, operator=
vyvolá InvalidOperationException.
Poznámky
Přiřazení objektu com::ptr
COM k odkazu 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á com::ptr
k zabalení jeho objektu soukromého člena IXMLDOMDocument
. Členová ReplaceDocument
funkce nejprve volá Release
jakýkoli dříve vlastněný objekt 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
který je bezpečnější než bool
proto, že jej nelze převést na celočíselný typ.
Příklad
Tento příklad implementuje třídu CLR, která používá com::ptr
k zabalení jeho objektu soukromého člena IXMLDOMDocument
. Členská CreateInstance
funkce použije operator bool
po vytvoření nového objektu dokumentu k určení, zda je platný a zapisuje do konzoly, pokud je.
// 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á com::ptr
k zabalení jeho objektu soukromého člena IXMLDOMDocument
. Členová CreateInstance
funkce používá operator!
k určení, zda je objekt dokumentu již vlastněný, a pouze vytvoří novou instanci, pokud 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.
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro