c++ dll中的内存泄漏

Memory leaks in c++ dll

本文关键字:内存 泄漏 dll c++      更新时间:2023-10-16

我有一个简单的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,一切都OK。

如何解决这个问题?

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

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