_com_ptr_t的使用

330 篇文章 4 订阅 ¥19.90 ¥99.00
这篇博客介绍了如何利用VC运行库中的_com_ptr_t智能指针类来简化DirectShow中COM接口的管理,包括自动处理AddRef和Release,以及在复制和释放接口时的注意事项。示例代码展示了如何创建和使用IGraphBuilder, IMediaControl和IMediaEvent接口。" 89225399,7367961,二叉树遍历与机器学习专项-编程Day28,"['算法', '数据结构', '机器学习']
摘要由CSDN通过智能技术生成

对于COM调用,大量的AddRef/Release调用无疑是例行公事和让人生厌。

_com_ptr_t 是vc运行库中提供的固有的封装COM接口的智能指针,相比CComPtr/CComQIPtr缺少移植性,但是支持不是ATL实现部分的的异常和操作。

以下是DirectShow中播放一个文件的代码:

    IGraphBuilder *pGraph;
    IMediaControl *pMediaControl;
    IMediaEvent   *pEvent;
   
    // Create the filter graph manager and query for interfaces.
    CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
                        IID_IGraphBuilder, (void **)&pGraph);
    pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
    pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

    // Build the graph. IMPORTANT: Change string to a file on your system.
    pGraph->RenderFile(L"C://Example.avi", NULL);

    // Run the graph.
    pMediaControl->Run();

    // Wait for completion.
    long evCode;
    pEvent->WaitForCompletion(INFINITE, &evCode);

    // Clean up.
    pMediaControl->Release();
    pEvent->Release();
    pGraph->Release();


使用com_ptr_t后简单了很多:

//这部分可以放到头文件中

#include
_COM_SMARTPTR_TYPEDEF( IGraphBuilder , __uuidof(IGraphBuilder) );
_COM_SMARTPTR_TYPEDEF( IMediaControl , __uuidof(IMediaControl) );
_COM_SMARTPTR_TYPEDEF( IMediaEvent , __uuidof(IMediaEvent) );

...

    IGraphBuilderPtr pGraph( CLSID_FilterGraph ) ;//调用CreateInstance
    IMediaControlPtr pMediaControl = pGraph;//这里会自动调用QueryInterface  
    IMediaEventPtr pEvent = pGraph;
//这里会自动调用QueryInterface
  
  pGraph->RenderFile( L"L"C://Example.avi", NULL); 
  

    // Run the graph.
    pMediaControl->Run();

    // Wait for completion.
    long evCode;
    pEvent->WaitForCompletion(INFINITE, &evCode);
//不需要调用Release()

假如我们要复制一个接口,常常要

pG1 = pG2;

pG1->AddRef();

...

pG1->Release();

对于_com_ptr_t , 只要pG1 = pG2;就可以了

注意以下的代码:

IGraphBuilderPtr pGraph ;

pGraph.CreateInstance( CLSID_FilterGraph );

...

CoUninitialize();

因为 pGraph 会在超出作用域时析构,也就是在CoUninitialize()之后调用 IUnkown::Release() ,这样会引起问题,可以这样解决:

pGraph.Release();  CoUninitialize();

或者

pGraph = NULL;  CoUninitialize(); //这样会隐含的调用_com_ptr_t::Release()

绝对不可以调用pGraph->Release();  因为这是调用IUnkown::Release()然后再调用一次pGraph.Release();  将会两次释放接口指针。

 

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值