Emidee
Emidee

Reputation: 1275

Double pointer function argument and CComPtr

I'm not sure of this way of using CComPtr inside of a function which has an argument expressed as a double pointer:

HRESULT D3DPresentEngine::CreateD3DSample(
    IDirect3DSwapChain9 *pSwapChain, 
    IMFSample **ppVideoSample
    )
{
    // Caller holds the object lock.

    D3DCOLOR clrBlack = D3DCOLOR_ARGB(0xFF, 0x00, 0x00, 0x00);

    CComPtr< IDirect3DSurface9 > pSurface;
    CComPtr< IMFSample > pSample;

    // Get the back buffer surface.
    ReturnIfFail( pSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurface ) );

    // Fill it with black.
    ReturnIfFail( m_pDevice->ColorFill(pSurface, NULL, clrBlack));

    // Create the sample.
    ReturnIfFail( MFCreateVideoSampleFromSurface(pSurface, &pSample));

    // Return the pointer to the caller.
    *ppVideoSample = pSample;
    (*ppVideoSample)->AddRef();

    return S_OK;
}

I have a doubt about the last assignation + AddRef call.

Are they OK for you?

Thanks in advance

Upvotes: 3

Views: 1367

Answers (3)

Raymond Chen
Raymond Chen

Reputation: 45173

The more idiomatic version would be

// Transfer the pointer to our caller.
*ppVideoSample = pSample.Detach();

If you want copy semantics rather than transfer, you would use

pSample.CopyTo(ppVideoSample);

Upvotes: 3

meklarian
meklarian

Reputation: 6625

The assignment and dereference for AddRef() are correct.

When MFCreateVideoSampleFromSurface() is called, the second argument to it is the location where the pointer to the interface should be stored. You use &pSample to obtain the address to pass to the function. This matches the IMFSample ** type required. Note that the & operator on CComPtr<> via CComPtrBase<> returns the correct type.

CComPtrBase::& operator @ MSDN

ppVideoSample is type IMFSample ** as well, which requires the * operator to dereference the interface pointer. That yields a pointer of type IMFSample *, which you can call with the -> operator to access AddRef() and other functions on the interface.

Upvotes: 0

Henrik
Henrik

Reputation: 23324

It's OK, but could be simplified:

HRESULT D3DPresentEngine::CreateD3DSample(
    IDirect3DSwapChain9 *pSwapChain, 
    IMFSample **ppVideoSample
    )
{
    // Caller holds the object lock.

    D3DCOLOR clrBlack = D3DCOLOR_ARGB(0xFF, 0x00, 0x00, 0x00);

    CComPtr< IDirect3DSurface9 > pSurface;

    // Get the back buffer surface.
    ReturnIfFail( pSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurface ) );

    // Fill it with black.
    ReturnIfFail( m_pDevice->ColorFill(pSurface, NULL, clrBlack));

    // Create the sample.
    ReturnIfFail( MFCreateVideoSampleFromSurface(pSurface, ppVideoSample));

    return S_OK;
}

In your code, the AddRef is necessary, because pSample will Release when it goes out of scope.

Upvotes: 3

Related Questions