Say I have a class that owns a D3DDevice
:
class Thing
{
public:
Thing()
{
D3D11CreateDevice(..., &device, ...);
}
~Thing()
{
device->Release();
}
private:
ID3D11Device* device;
};
From what I understand, I can use _com_ptr_t
to ensure that the object gets deleted without my having to explicitly call Release()
in the destructor. The problem though is that I can't figure out the correct syntax for the template.
I could find hardly any information on _com_ptr_t
, and the closest thing I could find to an answer was this (Japanese) one. Following the syntax there, I get a bunch of compiler errors:
private:
//ID3D11Device* device;
_com_ptr_t <_com_IIID<ID3D11Device, &__uuidof(ID3D11Device)>> device;
error C2143: syntax error : missing ';' before '<'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2238: unexpected token(s) preceding ';'
error C2065: 'device' : undeclared identifier
By the way, I can use this to return COM pointers from functions and ensure that they get deleted when they leave the caller's scope, right?
1) You can #import the appropriate type library, which will auto generate smart pointer types based on _com_ptr_t. 2) You can use the CComPtr template to wrap your raw COM pointer in a smart pointer that takes care of the resource management via automatic AddRef/Release calls, but doesn't give you much else.
The advantage of using _com_ptr_t over CComPtr/CComQIPtr is that you do not have to link to the ATL library. Other smart COM pointers that do not require the ATL library are _bstr_t (equivalent of CComBSTR) and _variant_t (equivalent of CComVariant ). > you do not have to link to the ATL library. That is very detailed and what I was looking for.
@HansPassant ah, so long as it's not something ginormous like enabling CLR support, which would have me reworking some amounts of code. _com_ptr_t is for defining a smart pointer type. For example let's define the IHTMLDocument3Ptr type: typedef _com_ptr_t <_com_IIID<IHTMLDocument3, &__uuidof (IHTMLDocument3)>> IHTMLDocument3Ptr;
_com_ptr_t is for defining a smart pointer type. For example let's define the IHTMLDocument3Ptr type:
typedef _com_ptr_t <_com_IIID<IHTMLDocument3, &__uuidof(IHTMLDocument3)>> IHTMLDocument3Ptr;
There is this simple macro for that:
_COM_SMARTPTR_TYPEDEF(IHTMLDocument3, IID_IHTMLDocument3);
This creates IHTMLDocument3Ptr, a smart pointer:
IHTMLDocument3Ptr htmlDocument3;
Using CComQIPtr this would be defined as:
CComQIPtr<IHTMLDocument3> htmlDocument3;
There is the "comdefsp.h" file with predefined smart pointers for many COM interfaces (https://singularity.svn.codeplex.com/svn/base/Windows/Inc/comdefsp.h). The "comdef.h" file includes it automatically. For example a smart pointer for IDispatch is already defined:
IDispatchPtr dispatch;
Using CComPtr this would would be defined as:
CComPtr<IDispatch> dispatch;
The advantage of using _com_ptr_t
over CComPtr/CComQIPtr
is that you do not have to link to the ATL library.
Other smart COM pointers that do not require the ATL library are _bstr_t
(equivalent of CComBSTR
) and _variant_t
(equivalent of CComVariant
).
There are usually two ways of dealing with COM smart pointers that I would recommend:
1) You can #import the appropriate type library, which will auto generate smart pointer types based on _com_ptr_t.
2) You can use the CComPtr template to wrap your raw COM pointer in a smart pointer that takes care of the resource management via automatic AddRef/Release calls, but doesn't give you much else.
Because I'm a little lazy and normally I don't mind the implicit overhead of the wrapper auto-generated by #import
, I usually use 1). One of the big benefits of using that approach is that the #import
mechanism also generates function wrappers that make COM functions look more like normal functions with proper return types and a translation of the HRESULT
to _com_error
exception objects. IMHO that tends to improve the control flow in C++ COM code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With