討論區快速選單
知識庫快速選單
最完整AWS雲端解決方案培訓 討論區最近新進100則主題 傑米的攝影旅遊筆記
[ 回上頁 ] [ 討論區發言規則 ]
(Directshow)pMoniker->BindToObject產生Memory leak問題
更改我的閱讀文章字型大小
作者 : wushing(小無)
[ 貼文 5 | 人氣 1 | 評價 0 | 評價/貼文 0 | 送出評價 2 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2014/11/20 上午 09:58:30
各位好
     小弟透過pMoniker->BindToObject的方式,想把找到的影像裝置綁定到Filter,但總會有memory leak的問題產生
,尋找之下才知道是這BindToObject造成的,下面列出部分小弟使用的程式,想請前輩指導,有任何問題請多多指導,謝謝!




// Create the system device enumerator
    hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
     IID_ICreateDevEnum, (void **) &pDevEnum);
    if (FAILED(hr))
    {
     //Msg(TEXT("Couldn't create system enumerator! hr=0x%x"), hr);
    }

    // Create an enumerator for the video capture devices

if (SUCCEEDED(hr))
{
hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
if (FAILED(hr))
{
//Msg(TEXT("Couldn't create class enumerator! hr=0x%x"), hr);
}
}

if (SUCCEEDED(hr))
{
// If there are no enumerators for the requested type, then
// CreateClassEnumerator will succeed, but pClassEnum will be NULL.
if (pClassEnum == NULL)
{

hr = E_FAIL;
}
}

if (SUCCEEDED(hr))
{
hr = pClassEnum->Next(1, &pMoniker, NULL);
if (hr == S_FALSE)
{
//Msg(TEXT("Unable to access video capture device!"));
hr = E_FAIL;
}
}

if (SUCCEEDED(hr))
    {
     // Bind Moniker to a filter object
     hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)&pSrc);
     if (FAILED(hr))
     {
     //Msg(TEXT("Couldn't bind moniker to filter object! hr=0x%x"), hr);
hr = E_FAIL;
     }
    }
作者 : ozzy123(ozzy) 資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4462 | 人氣 37262 | 評價 10860 | 評價/貼文 2.43 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2014/11/20 上午 10:14:56
would you please post your error message ?
作者 : wushing(小無)
[ 貼文 5 | 人氣 1 | 評價 0 | 評價/貼文 0 | 送出評價 2 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2014/11/20 上午 11:59:37
I got no ErrorMessage.
I find this memory leak problem ,by using https://vld.codeplex.com/

I read the remarks on msdn

The moniker calls this method in its implementations of the IMoniker::BindToObject and IMoniker::BindToStorage methods to obtain information about the specific bind operation.
Asynchronous moniker clients should be aware that a moniker might call this method multiple times during a bind operation. A correct implementation of IBindStatusCallback::GetBindInfo should prepare for this possibility. If returning data in the pbindinfo parameter, the implementation should allocate the appropriate data (szExtraInfo and stgmedData) at the time of each call. In this manner, if the callback is never called, data is never allocated; if the callback is called multiple times, it will work correctly. The first time this callback is received by the asynchronous moniker client is before the call to IMoniker::BindToStorage or IMoniker::BindToObject.
Even when the value of grfBindInfoF is BINDF_ASYNCHRONOUS, it is possible that the original call to IMoniker::BindToStorage or IMoniker::BindToObject might return synchronously instead of returning the MK_S_ASYNCHRONOUS flag. Clients of asynchronous monikers should always prepare for this possibility. Specifically, to avoid memory leaks, you must make sure that you release the pointer returned by a call to either method.
One way to deal with this case is to call your own implementation of IBindStatusCallback::OnDataAvailable or IBindStatusCallback::OnObjectAvailable to use the same code path, regardless of whether you bind synchronously or asynchronously.
If the BINDF_PULLDATA value is not set in the grfBindInfoF parameter, Urlmon.dll sets the BINDF_NEEDFILE value. If BINDF_NEEDFILE is set, binding of resources that cannot be cached (such as an HTTPS resource) will fail.

I thnk maybe this will help.
作者 : ozzy123(ozzy) 資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4462 | 人氣 37262 | 評價 10860 | 評價/貼文 2.43 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2014/11/20 下午 01:55:31
you may launch Vc++ debugger or add some exception handling codes for them.
作者 : ozzy123(ozzy) 資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4462 | 人氣 37262 | 評價 10860 | 評價/貼文 2.43 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人wushing註記此篇回應為很有道理 2014/11/20 下午 02:04:17
http://msdn.microsoft.com/en-us/library/Aa293901(VS.60).aspx
作者 : gmailjoey(建中)
[ 貼文 199 | 人氣 0 | 評價 190 | 評價/貼文 0.95 | 送出評價 12 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人wushing註記此篇回應為最佳解答 2014/11/20 下午 02:54:15
加入微軟規定的除錯程式碼可以關掉Runtime Check,
關掉Runtime Check以後可以確實呼叫出堆疊毀損的視窗。

請把下面的微軟程式碼加到你的程式:
//------加入下面這一個MyErrorHandler函式

#pragma runtime_checks("", off)

// RTC Error Handler
int MyErrorHandler(int errType, const char* file, int line,
    const char* module, const char* format, ...)
{
    // 1. Prevent re-entrance
    static long IsRunning = 0;
    while ( InterlockedExchange(&IsRunning, 1) )
     Sleep(1);

    // 2. Get the RTC error number from the var_arg list
    va_list ArgList;
    va_start(ArgList, format);
    _RTC_ErrorNumber ErrorNumber = va_arg(ArgList, _RTC_ErrorNumber);
    va_end(ArgList);

    char s[1024];
    // 3. Get the error description
    const char* ErrorDesc = _RTC_GetErrDesc(ErrorNumber);
    sprintf_s(s, sizeof(s), "%s occured.\nLine: %i\nFile: %s\nModule: %s\nClick OK to break into debugger.",
     ErrorDesc, line, file ? file : "Unknown",
     module ? module : "Unknown");
   
 // 4. Display message box
    MessageBoxA(NULL, s, "Run-Time Error", MB_OK);
    // 5. Go ahead and break into the debugger
    return 1;
}
#pragma runtime_checks("", restore)

//-----加入的程式碼到此為止

//-----並且修改int _tmain

int _tmain(...)
{
...

if (SUCCEEDED(hr))
   {

     //
     _RTC_error_fn OldHandler; //<----加入這一行除錯程式碼
     OldHandler = _RTC_SetErrorFunc(&MyErrorHandler); //<----加入這一行除錯程式碼


     // Bind Moniker to a filter object下面這一行需要除錯
     hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)&pSrc);
     if (FAILED(hr))
     {
     //Msg(TEXT("Couldn't bind moniker to filter object! hr=0x%x"), hr);
hr = E_FAIL;
     }

     _RTC_SetErrorFunc(OldHandler); //<----加入這一行除錯程式碼
    }



}

照著以上的方式修改好程式以後可以關掉Runtime Check,
就可以正確找出堆疊毀損或是memory leak的錯誤訊息了。
全部除錯完成以後再把除錯程式碼移除就可以了。
 板主 : 白老鼠(Gary)
 > DirectX - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - DirectX - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
DirectX
1 aming 4010 
2 pernghy 1780 
3 白老鼠(Gary) 1120 
4 Akira 1020 
5 冷眼 980 
6 PLAYER 690 
7 阿西德倫 480 
8 andre 450 
9 小弦 430 
10 藍斯洛 410 
DirectX
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2018 程式設計俱樂部 http://www.programmer-club.com.tw/
0.0625