Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use _com_ptr_t?

Tags:

c++

com

Say I have a class that owns a D3DDevice:

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

From what I understand, I can use _com_ptr_t to ensure that the object gets deleted without my having to explicitly call Release() in the destructor. The problem though is that I can't figure out the correct syntax for the template.

I could find hardly any information on _com_ptr_t, and the closest thing I could find to an answer was this (Japanese) one. Following the syntax there, I get a bunch of compiler errors:

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

By the way, I can use this to return COM pointers from functions and ensure that they get deleted when they leave the caller's scope, right?

like image 769
Rei Miyasaka Avatar asked Apr 14 '12 13:04

Rei Miyasaka


People also ask

How to make a COM pointer into a smart pointer?

1) You can #import the appropriate type library, which will auto generate smart pointer types based on _com_ptr_t. 2) You can use the CComPtr template to wrap your raw COM pointer in a smart pointer that takes care of the resource management via automatic AddRef/Release calls, but doesn't give you much else.

What is the advantage of using _COM_PTR_T over ccomptr/ccomqiptr?

The advantage of using _com_ptr_t over CComPtr/CComQIPtr is that you do not have to link to the ATL library. Other smart COM pointers that do not require the ATL library are _bstr_t (equivalent of CComBSTR) and _variant_t (equivalent of CComVariant ). > you do not have to link to the ATL library. That is very detailed and what I was looking for.

What does the _com_PTR_T type do?

@HansPassant ah, so long as it's not something ginormous like enabling CLR support, which would have me reworking some amounts of code. _com_ptr_t is for defining a smart pointer type. For example let's define the IHTMLDocument3Ptr type: typedef _com_ptr_t <_com_IIID<IHTMLDocument3, &__uuidof (IHTMLDocument3)>> IHTMLDocument3Ptr;


2 Answers

_com_ptr_t is for defining a smart pointer type. For example let's define the IHTMLDocument3Ptr type:

typedef _com_ptr_t <_com_IIID<IHTMLDocument3, &__uuidof(IHTMLDocument3)>> IHTMLDocument3Ptr;

There is this simple macro for that:

_COM_SMARTPTR_TYPEDEF(IHTMLDocument3, IID_IHTMLDocument3);

This creates IHTMLDocument3Ptr, a smart pointer:

IHTMLDocument3Ptr htmlDocument3;

Using CComQIPtr this would be defined as:

CComQIPtr<IHTMLDocument3> htmlDocument3;

There is the "comdefsp.h" file with predefined smart pointers for many COM interfaces (https://singularity.svn.codeplex.com/svn/base/Windows/Inc/comdefsp.h). The "comdef.h" file includes it automatically. For example a smart pointer for IDispatch is already defined:

IDispatchPtr dispatch;

Using CComPtr this would would be defined as:

CComPtr<IDispatch> dispatch;

_com_ptr_t = no ATL

The advantage of using _com_ptr_t over CComPtr/CComQIPtr is that you do not have to link to the ATL library.

Other smart COM pointers that do not require the ATL library are _bstr_t (equivalent of CComBSTR) and _variant_t (equivalent of CComVariant).

like image 96
Czarek Tomczak Avatar answered Sep 18 '22 14:09

Czarek Tomczak


There are usually two ways of dealing with COM smart pointers that I would recommend:

1) You can #import the appropriate type library, which will auto generate smart pointer types based on _com_ptr_t.

2) You can use the CComPtr template to wrap your raw COM pointer in a smart pointer that takes care of the resource management via automatic AddRef/Release calls, but doesn't give you much else.

Because I'm a little lazy and normally I don't mind the implicit overhead of the wrapper auto-generated by #import, I usually use 1). One of the big benefits of using that approach is that the #import mechanism also generates function wrappers that make COM functions look more like normal functions with proper return types and a translation of the HRESULT to _com_error exception objects. IMHO that tends to improve the control flow in C++ COM code.

like image 38
Timo Geusch Avatar answered Sep 21 '22 14:09

Timo Geusch