问题
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:
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.
回答2:
_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;
_com_ptr_t = no ATL
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).
回答3:
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 parsing
comdef.h should fix both problems (see code listed)
来源:https://stackoverflow.com/questions/10153873/how-do-i-use-com-ptr-t