我如何使用_com_ptr_t?

Rei*_*aka 5 c++ com

假设我有一个拥有一个D3DDevice:

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

根据我的理解,我可以使用_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
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我可以使用它来从函数返回COM指针,并确保它们在离开调用者的范围时被删除,对吧?

Cza*_*zak 17

_com_ptr_t用于定义智能指针类型.例如,让我们定义IHTMLDocument3Ptr类型:

typedef _com_ptr_t <_com_IIID<IHTMLDocument3, &__uuidof(IHTMLDocument3)>> IHTMLDocument3Ptr;
Run Code Online (Sandbox Code Playgroud)

有这个简单的宏:

_COM_SMARTPTR_TYPEDEF(IHTMLDocument3, IID_IHTMLDocument3);
Run Code Online (Sandbox Code Playgroud)

这创建了IHTMLDocument3Ptr,一个智能指针:

IHTMLDocument3Ptr htmlDocument3;
Run Code Online (Sandbox Code Playgroud)

使用CComQIPtr,这将被定义为:

CComQIPtr<IHTMLDocument3> htmlDocument3;
Run Code Online (Sandbox Code Playgroud)

有一个"comdefsp.h"文件,其中包含许多COM接口的预定义智能指针(https://singularity.svn.codeplex.com/svn/base/Windows/Inc/comdefsp.h)."comdef.h"文件自动包含它.例如,已经定义了IDispatch的智能指针:

IDispatchPtr dispatch;
Run Code Online (Sandbox Code Playgroud)

使用CComPtr这将被定义为:

CComPtr<IDispatch> dispatch;
Run Code Online (Sandbox Code Playgroud)

_com_ptr_t =没有ATL

使用_com_ptr_tover 的优点CComPtr/CComQIPtr您不必链接到ATL库.

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


Tim*_*sch 7

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

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

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

因为我有点懒,通常我不介意自动生成的包装器的隐式开销#import,我通常使用1).对使用这种方法的最大好处是,#import机制也产生功能的包装,使COM功能看起来更像是正确的返回类型的正常功能和的翻译HRESULT_com_error异常对象.恕我直言,倾向于改善C++ COM代码中的控制流程.