内存泄漏c ++ dll

时间:2013-06-18 20:08:23

标签: c++ winapi memory-leaks gdi

我有简单的c ++ dll,其中包含用于屏幕捕获的代码。

HBITMAP hCaptureBitmap;

extern "C" __declspec(dllexport)  HBITMAP  __stdcall CaptureScreenByGDI(bool allScreens)
{
    int nScreenWidth;
    int nScreenHeight;
    HDC hDesktopDC;

    if(allScreens)
    {
        nScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
        nScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    }
    else
    {
        nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
        nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
    }

    HWND hDesktopWnd = GetDesktopWindow();

    if(allScreens)
    {
        hDesktopDC = GetDC(NULL);
    }
    else
    {
        hDesktopDC = GetDC(hDesktopWnd);
    }

    HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);
    hCaptureBitmap =CreateCompatibleBitmap(hDesktopDC, 
        nScreenWidth, nScreenHeight);

    SelectObject(hCaptureDC,hCaptureBitmap); 

    BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight,
        hDesktopDC,0,0,SRCCOPY|CAPTUREBLT); 

    ReleaseDC(hDesktopWnd,hDesktopDC);
    DeleteDC(hCaptureDC);

    return hCaptureBitmap;
}

extern "C" __declspec(dllexport)  void __stdcall ClearAfterGDI()
{
    DeleteObject(hCaptureBitmap);
}

致电后

CaptureScreenByGDI(true);
ClearAfterGDI();
来自c#的

仍然是内存泄漏。为什么? 如果我从CaptureScreenByGDI函数调用DeleteObject(hCaptureBitmap)并返回void everthing就可以了。

如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

您需要在创建的DC中保存旧位图并在删除DC之前将其恢复:

HGDIOBJ hBmpOld = SelectObject(hCaptureDC,hCaptureBitmap); 
...
SelectObject(hCaptureDC, hBmpOld);
DeleteDC(hCaptureDC);