c++ - C++ dll中的内存泄漏

标签 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,一切正常。

如何解决?

最佳答案

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

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

关于c++ - C++ dll中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17177940/

相关文章:

winapi - 使用 GDIPlus (WIn32 C++) 显示存储为带 alpha 资源的图标

Windows关闭然后启动后c++服务不会启动

javascript - 防止 Angular 2 中的内存泄漏?

linux - 如何发现进程的内存泄漏?

java - 无法在 spring boot 应用程序中启用 native 内存跟踪

C++ map 定义基础

c++ - 调用 glBindVertexArray(vao) : what does it do if 'vao' is already bound, 以及如何相应地设计形状类?

c++ - recvfrom() 是否在出错时修改 src_addr?

c++ - 模板中有两个默认参数,这里有什么问题?

c - WinAPI 命名管道位置