智能指針 _com_ptr_t的使用

對於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();  將會兩次釋放接口指針。

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/ljfxmf/archive/2008/06/04/2511029.aspx

發佈了7 篇原創文章 · 獲贊 3 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章