2012-03-06 3 views
1

私は私のコードでは、このコールにメモリリークを突き止めました:メモリリーク++/CLI方法

BitmapSource snapshot = VideoPlayer.GetCurrentImage(); 

のVideoPlayerはC++/CLIライブラリであり、このメソッドのコードは次のとおりです。

WriteableBitmap^ VideoPlayback::GetCurrentImage() 
{ 
    BITMAPINFOHEADER bih; 
    BYTE *pDib = 0; 
    DWORD cbDib = 0; 
    LONGLONG timeStamp = 0; 

    memset(&bih, 0, sizeof(bih)); 
    bih.biSize = sizeof(BITMAPINFOHEADER); 
    HRESULT hr = m_pPlayer->GetCurrentImage(&bih, &pDib, &cbDib, &timeStamp); 

    if (FAILED(hr)) throw gcnew MFException(hr); 

    WriteableBitmap^ res = ToWritableBitmap(bih, pDib, cbDib, true); 

    CoTaskMemFree(pDib); 

    return res; 
} 

とToWriteableBitmap:いくつかのオブジェクトで

WriteableBitmap^ VideoPlayback::ToWritableBitmap(const BITMAPINFOHEADER& bih, BYTE* pDib, DWORD cbDib, bool bInvert) 
{ 
    WriteableBitmap^ res; 
    AtlTrace(_T("image size: %d x %d, bitCount: %d, bufferSize: %d\n"), bih.biWidth, bih.biHeight, bih.biBitCount, cbDib); 

    switch (bih.biBitCount) 
    { 
     //could there be any other format!? 
    case 24: 
     //AtlTrace(_T("24bit image not supported!")); 
     res = gcnew WriteableBitmap(bih.biWidth, bih.biHeight, 72.0, 72.0, System::Windows::Media::PixelFormats::Bgr24, nullptr); 
     break; 
    case 32: 
     res = gcnew WriteableBitmap(bih.biWidth, bih.biHeight, 72.0, 72.0, System::Windows::Media::PixelFormats::Bgr32, nullptr); 
     break; 
    } 
    if (res!=nullptr) 
    { 
     int stride = res->BackBufferStride; 
     res->Lock(); 

     if (bInvert) 
     { 
      BYTE* pBuf = (BYTE*)res->BackBuffer.ToPointer(); 

      BYTE* pDest = pBuf + (bih.biHeight - 1) * stride; 
      BYTE* pSrc = pDib; 
      //the image is inverted 
      for (int y = 0; y < bih.biHeight; y++) 
      { 
       memcpy(pDest, pSrc, stride); 
       pSrc+=stride; 
       pDest-=stride; 
      } 
     } 
     else 
     { 
      BYTE* pDest = (BYTE*)res->BackBuffer.ToPointer(); 
      memcpy(pDest, pDib, bih.biSizeImage); 
     } 

     res->AddDirtyRect(System::Windows::Int32Rect(0, 0, bih.biWidth, bih.biHeight)); 
     res->Unlock(); 
    } 
    return res; 
} 

呼び出すと、このメソッドを複数回の結果が「固定」されていると高いDeadThr私がwindbgで!threadsを実行したときのeadカウント。 >
00000000125f0c08(System.Collections.ArrayList) - 0000000022423378(System.Objectの[]):

DOMAIN(00000000036553A0):HANDLEする(固定):5417c8:ルート私が得るこれらの死者のスレッド上!gcrootを実行します - >
0000000012d96950(System.Objectの[]) - >
0000000012e44460(System.Windows.Media.MediaContext) - >
0000000012e43e80(System.Windows.Threading.Dispatcher) - >
0000000012e30480(System.Threading。スレッド)

System.Object[]のアドレスは常に同じです。

スレッドが終了できるように、この呼び出しの後に適切にクリーンアップするにはどうすればよいですか?それとも、C++コードに問題がありますか?

+1

CLRは静的オブジェクトを格納するために固定オブジェクト配列を使用します。私はソースで静的なArrayListを探します。 –

+1

もっとコードを添付する必要があると思います。私の推測は 'ToWritableBitmap'関数です。データをコピーしませんか? – Krizz

+0

あなたはスレッドがたくさんあると言っていますが、投稿したコードにはスレッドがあります。多分それはあなたが調べなければならないものですか? – svick

答えて

0

問題はバックグラウンドスレッドでBitmapSourceを作成していることでした。 Dispatcher.Invokeを使ってこのメソッドを呼び出すと、スレッドのリークがなくなりました。

関連する問題