如何使用_com_ptr_t

How do I use _com_ptr_t?

本文关键字:ptr com 何使用      更新时间:2023-10-16

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

_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://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-headers/include/comdefsp.h)的预定义智能指针。"comdef.h"文件会自动包含它。例如,已经定义了 IDispatch 的智能指针:

IDispatchPtr dispatch;

使用 CComPtr 这将定义为:

CComPtr<IDispatch> dispatch;

_com_ptr_t = 无 ATL

CComPtr/CComQIPtr相比,使用 _com_ptr_t 的优点是不必链接到 ATL 库

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

我通常推荐两种处理 COM 智能指针的方法:

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

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

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

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

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