假设我有一个拥有D3DDevice
的小组:
class Thing
{
public:
Thing()
{
D3D11CreateDevice(..., &device, ...);
}
~Thing()
{
device->Release();
}
private:
ID3D11Device* device;
};
根据我的理解,我可以使用_com_ptr_t
来确保删除对象,而不必在析构函数中显式调用Release()
。但问题是我无法找出模板的正确语法。
我几乎找不到关于_com_ptr_t
的任何信息,而我能找到答案的最接近的是this (Japanese) one。遵循语法,我得到了一堆编译器错误:
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
顺便说一句,我可以使用它来从函数中返回COM指针并确保它们在离开调用者的范围时被删除,对吗?
答案 0 :(得分:16)
_com_ptr_t用于定义智能指针类型。例如,让我们定义IHTMLDocument3Ptr类型:
typedef _com_ptr_t <_com_IIID<IHTMLDocument3, &__uuidof(IHTMLDocument3)>> IHTMLDocument3Ptr;
有这个简单的宏:
_COM_SMARTPTR_TYPEDEF(IHTMLDocument3, IID_IHTMLDocument3);
这会创建一个智能指针IHTMLDocument3Ptr:
IHTMLDocument3Ptr htmlDocument3;
使用CComQIPtr,这将被定义为:
CComQIPtr<IHTMLDocument3> htmlDocument3;
“comdefsp.h”文件包含许多COM接口(https://singularity.svn.codeplex.com/svn/base/Windows/Inc/comdefsp.h)的预定义智能指针。 “comdef.h”文件自动包含它。例如,已经定义了IDispatch的智能指针:
IDispatchPtr dispatch;
使用CComPtr,这将被定义为:
CComPtr<IDispatch> dispatch;
使用_com_ptr_t
优于CComPtr/CComQIPtr
的优势在于您无需链接到ATL库。
其他不需要ATL库的智能COM指针是_bstr_t
(相当于CComBSTR
)和_variant_t
(相当于CComVariant
)。
答案 1 :(得分:7)
我建议通常有两种处理COM智能指针的方法:
1)你可以#import相应的类型库,它将根据_com_ptr_t自动生成智能指针类型。
2)您可以使用CComPtr模板将原始COM指针包装在智能指针中,该指针通过自动AddRef / Release调用来处理资源管理,但不会为您提供更多其他内容。
因为我有点懒,通常我不介意#import
自动生成的包装器的隐式开销,我通常使用1)。使用该方法的一大好处是#import
机制还生成函数包装器,使COM函数看起来更像正常函数,具有正确的返回类型以及HRESULT
到{{1}的转换异常对象。恕我直言,倾向于改善C ++ COM代码中的控制流程。
答案 2 :(得分:3)
您问题中第二个代码的错误意味着编译器不知道<
之前的一个(或两个)类型:您需要包含正确的标头以确保_com_ptr_t
_com_IIID
是有效且已知的类型。此外,>>
可能被解析为“shift-right”运算符,在它们之间放置一个空格以允许正确的可移植解析
comdef.h
应该fix both problems(参见所列代码)