【问题标题】:Double pointer function argument and CComPtr双指针函数参数和 CComPtr
【发布时间】:2011-11-08 00:34:33
【问题描述】:

我不确定在函数内部使用 CComPtr 的这种方式,该函数的参数表示为双指针:

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;
}

我对最后一次分配 + AddRef 调用有疑问。

它们适合你吗?

提前致谢

【问题讨论】:

    标签: c++ atl smart-pointers


    【解决方案1】:

    没关系,但可以简化:

    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;
    }
    

    在您的代码中,AddRef 是必需的,因为当它超出范围时,pSample 将是 Release

    【讨论】:

      【解决方案2】:

      更惯用的版本是

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

      如果你想要复制语义而不是转移,你会使用

      pSample.CopyTo(ppVideoSample);
      

      【讨论】:

        【解决方案3】:

        AddRef() 的赋值和取消引用是正确的。

        MFCreateVideoSampleFromSurface() 被调用时,它的第二个参数是指向接口的指针应该被存储的位置。您使用&amp;pSample 获取要传递给函数的地址。这与所需的 IMFSample ** 类型匹配。请注意,CComPtr&lt;&gt; 上的 &amp; 运算符通过 CComPtrBase&lt;&gt; 返回正确的类型。

        CComPtrBase::& operator @ MSDN

        ppVideoSample 也是IMFSample ** 类型,这需要* 运算符取消对接口指针的引用。这会产生一个IMFSample * 类型的指针,您可以使用-&gt; 运算符调用它来访问AddRef() 和接口上的其他函数。

        【讨论】:

          猜你喜欢
          • 2012-12-29
          • 1970-01-01
          • 2014-09-26
          • 1970-01-01
          • 2016-09-07
          • 1970-01-01
          • 2011-03-27
          • 2011-06-17
          相关资源
          最近更新 更多