You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

函数返回CComPtr<IMFSample>是否合规?引用计数是否正确?

这种做法完全可行,而且是COM编程中推荐的最佳实践之一,引用计数也会保持正确!

CComPtr作为ATL的智能指针,核心作用就是自动管理COM对象的引用计数,所以直接返回CComPtr<IMFSample>是非常合理的。具体原理是:

  • 当你在函数内部通过MFCreateSample或其他COM创建函数初始化CComPtr<IMFSample>时,智能指针会自动调用AddRef持有对象引用。
  • 函数返回时,CComPtr的拷贝构造函数会自动对对象调用一次AddRef,把引用传递给调用者的智能指针。
  • 函数内部的局部CComPtr实例在函数退出时会被销毁,自动调用Release——此时对象的引用计数会减去1,刚好和返回时的AddRef抵消,最终调用者持有的引用计数完全正确。

下面是修正后的完整示例函数:

CComPtr<IMFSample> getSample() {
    HRESULT hr = S_OK;
    CComPtr<IMFSample> pSample;

    // 创建IMFSample实例
    hr = MFCreateSample(&pSample);
    if (FAILED(hr)) {
        // 错误处理:直接返回空指针,局部pSample会自动释放(如果已创建)
        return nullptr;
    }

    // 为Sample添加缓冲区的示例逻辑
    const DWORD bufferSize = 4096;
    CComPtr<IMFMediaBuffer> pBuffer;
    hr = MFCreateMemoryBuffer(bufferSize, &pBuffer);
    if (SUCCEEDED(hr)) {
        // pBuffer的引用会被IMFSample持有,无需手动管理
        hr = pSample->AddBuffer(pBuffer);
    }

    // 如果中途出错,pSample会自动释放已创建的对象;成功则返回有效引用
    return pSample;
}

额外补充几点注意事项:

  • 绝对不要在返回前手动调用pSample->AddRef(),否则会导致引用计数多增一次,最终造成内存泄漏。
  • 调用者使用时直接用CComPtr<IMFSample> mySample = getSample();即可,无需手动调用Release,智能指针会在生命周期结束时自动清理。
  • 如果函数中途失败返回nullptr,内部所有已创建的CComPtr(包括pSample和pBuffer)都会自动销毁,正确释放对应的COM对象,不会产生泄漏。

内容的提问来源于stack exchange,提问作者Gary G.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:22:17