2013-06-18 136 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