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?
_com_ptr_t is for defining a smart pointer type. For example let's define the IHTMLDocument3Ptr type:
There is this simple macro for that:
This creates IHTMLDocument3Ptr, a smart pointer:
Using CComQIPtr this would be defined as:
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:
Using CComPtr this would would be defined as:
_com_ptr_t = no ATL
The advantage of using
_com_ptr_t
overCComPtr/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 ofCComBSTR
) and_variant_t
(equivalent ofCComVariant
).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 theHRESULT
to_com_error
exception objects. IMHO that tends to improve the control flow in C++ COM code.The errors from the second code in your question mean that the compiler does not know one (or both) of the types before the
<
: you need to include the proper headers to ensure both_com_ptr_t
and_com_IIID
are valid and known types. Also, the>>
might be parsed as "shift-right" operator, put a space between them to allow proper, portable parsingcomdef.h
should fix both problems (see code listed)