8

假设我有一个拥有 a 的类D3DDevice

class Thing
{
public:
    Thing()
    {
        D3D11CreateDevice(..., &device, ...);
    }
    ~Thing()
    {
        device->Release();
    }
private:
    ID3D11Device* device;
};

据我了解,我可以_com_ptr_t用来确保对象被删除,而无需显式调用Release()析构函数。但问题是我无法找出模板的正确语法。

我几乎找不到任何关于的信息_com_ptr_t,而我能找到的最接近答案的是这个(日语)。按照那里的语法,我得到了一堆编译器错误:

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 指针,并确保它们在离开调用者范围时被删除,对吗?

4

3 回答 3

25

_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_tover的优点CComPtr/CComQIPtr您不必链接到 ATL 库

其他不需要 ATL 库的智能 COM 指针是_bstr_t(equivalent of CComBSTR) 和_variant_t(equivalent of CComVariant)。

于 2013-01-31T13:41:02.290 回答
10

我建议通常有两种处理 COM 智能指针的方法:

1) 您可以#import 适当的类型库,它将根据_com_ptr_t 自动生成智能指针类型。

2) 您可以使用 CComPtr 模板将原始 COM 指针包装在一个智能指针中,该指针通过自动 AddRef/Release 调用处理资源管理,但不会给您提供太多其他信息。

因为我有点懒,通常我不介意由 自动生成的包装器的隐式开销,所以#import我通常使用 1)。使用这种方法的一大好处是,该#import机制还生成函数包装器,使 COM 函数看起来更像具有正确返回类型和异常对象转换的普通HRESULT函数_com_error。恕我直言,它倾向于改进 C++ COM 代码中的控制流。

于 2012-04-14T13:18:43.380 回答
3

您问题中第二个代码的错误意味着编译器在<: 之前不知道其中一种(或两种)类型,您需要包含正确的标头以确保两者都是有效_com_ptr_t_com_IIID已知的类型。此外,>>可能会被解析为“右移”运算符,在它们之间放置一个空格以允许正确、可移植的解析

comdef.h应该解决这两个问题(参见列出的代码)

于 2012-04-14T13:17:12.473 回答