2013-06-18 138 views
0

我有简单的c + + DLL包含屏幕捕获代码。内存泄漏在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); 
} 

从C#调用

CaptureScreenByGDI(true); 
ClearAfterGDI(); 

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

如何解决这个问题?

+0

应用程序验证程序可能会在某些情况下帮助。 –

回答

3

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

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

我真的不知道究竟是什么解决了这个问题,但是在我重新创建位图之前添加了代码+ DeleteObject(hCaptureBitmap)之后,在c#中添加bmp.Dispose()一切正常) – KTF