我如何使用_com_ptr_t?

时间:2012-04-14 13:07:12

标签: c++ com

假设我有一个拥有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指针并确保它们在离开调用者的范围时被删除,对吗?

3 个答案:

答案 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 =没有ATL

使用_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(参见所列代码)