Gdiplus :: Bitmap :: FromHBITMAP内存泄漏

时间:2017-07-25 14:34:07

标签: c++ bitmap gdi+

我反复调用此代码导致内存泄漏:

ULONG_PTR gdiplusToken;
int screen_height;
int screen_width;

CVCamStream::CVCamStream(HRESULT *phr, CVCam *pParent, LPCWSTR pPinName) : CSourceStream(LPCSTR(FILTER_NAME),phr, pParent, pPinName), m_pParent(pParent)
{
    hdc = GetDC(NULL);

    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    screen_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    screen_width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
}

CVCamStream::~CVCamStream()
{
    Gdiplus::GdiplusShutdown(gdiplusToken);
    DeleteDC(hdc);
} 

HRESULT CVCamStream::FillBuffer(IMediaSample *pms)
{
    REFERENCE_TIME rtNow;
    REFERENCE_TIME avgFrameTime = ((VIDEOINFOHEADER*)m_mt.pbFormat)->AvgTimePerFrame;

    static clock_t refClock = clock();
    double elapsed = (clock() - refClock) / (double)CLOCKS_PER_SEC;

    rtNow = m_rtLastTime;
    m_rtLastTime += avgFrameTime;
    pms->SetTime(&rtNow, &m_rtLastTime);
    pms->SetSyncPoint(TRUE);

    HDC memdc = CreateCompatibleDC(NULL);

    CImage image;
    image.Create(screen_width, screen_height, 24);
    SelectObject(memdc, image);

    BYTE *pData;
    pms->GetPointer(&pData);
    long lDataLen = pms->GetSize();

    Gdiplus::Bitmap *bitmap = new Gdiplus::Bitmap(screen_width, screen_height, PixelFormat24bppRGB);

    BitBlt(memdc, 0, 0, screen_width, screen_height, hdc, 0, 0, SRCCOPY);
    DeleteDC(memdc);

    // memdc is already deleted
    bitmap->FromHBITMAP(image, NULL);

    delete bitmap;
    image.Destroy();
    DeleteObject(image);
    DeleteDC(memdc);

    return NOERROR;
} 

但每次RAM使用量增加。违规行是FromHBITMAP()函数,因为在那里对它进行评论不再有泄漏。

我知道FromHBITMAP()创建了位图的副本,但我想我释放了所有的记忆!

这里有什么问题?

1 个答案:

答案 0 :(得分:0)

FromHBITMAP不会获取传递的位图句柄的所有权。您只需传递仍由CImage实例拥有的位图句柄。另外according to MSDN

  

不要将GDI位图或当前(或以前)选择的GDI调色板传递给Bitmap :: FromHBITMAP方法。

image仍然选择memdc时,您正在调用它。