Visual c++ 如何处理GDI资源泄漏

Visual c++ 如何处理GDI资源泄漏,visual-c++,gdi,Visual C++,Gdi,在我的应用程序中,我使用GetDC获取DC,并且使用ReleaseDC释放该DC 但是,当我使用VTune评测应用程序时,它在GetDC上显示GDIResource泄漏 m_hdc = ::GetDC(hWndDisplay[frameIndex]); ::SetStretchBltMode(m_hdc,STRETCH_DELETESCANS); ::StretchDIBits(m_hdc,0,0,IMAGE_WIDTH,IMAGE_HEIGHT,0,0,imageWidth,imageHeig

在我的应用程序中,我使用GetDC获取DC,并且使用ReleaseDC释放该DC

但是,当我使用VTune评测应用程序时,它在GetDC上显示GDIResource泄漏

m_hdc = ::GetDC(hWndDisplay[frameIndex]);
::SetStretchBltMode(m_hdc,STRETCH_DELETESCANS);
::StretchDIBits(m_hdc,0,0,IMAGE_WIDTH,IMAGE_HEIGHT,0,0,imageWidth,imageHeight,rgbavpg,pTempBmpInfo,DIB_RGB_COLORS,SRCCOPY);
::ReleaseDC(hWndDisplay[frameIndex],m_hdc);
以下是相关代码:m_hdc id全局定义为hdc m_hdc

void Display(unsigned char *rgbavpg,unsigned long imageSize, unsigned int imageWidth, unsigned int imageHeight, unsigned int frameIndex)
{

PBITMAPINFO pTempBmpInfo = NULL;
DWORD timespan;
int temp;

if ((IMAGE_WIDTH==imageWidth)&&(IMAGE_HEIGHT==imageHeight))
{
    frameNum++ ;
}
timespan = 1000/15;
DWORD diff = GetTickCount() - tickes[frameIndex];//lvm4;
tickes[frameIndex]=GetTickCount();
if (g_threadMarkedForStop[frameIndex] == TRUE ) 
{        
    return;
}
if(diff < timespan)
    { 
            Sleep(diff);
    }
if (FALSE == ::IsWindow(hWndDisplay[frameIndex])) 
{
    g_threadMarkedForStop[frameIndex] = TRUE
    return;
}

pTempBmpInfo = &m_bmpinfo[frameIndex];
if(pTempBmpInfo != NULL)
{
    pTempBmpInfo->bmiHeader.biWidth= imageWidth ;
    pTempBmpInfo->bmiHeader.biHeight= imageHeight;
}
else 
{
    g_threadMarkedForStop[frameIndex] = TRUE;

    return;
}
m_hdc = ::GetDC(hWndDisplay[frameIndex]);
     ::SetStretchBltMode(m_hdc,STRETCH_DELETESCANS);

if (true == fullscreen)                ::StretchDIBits(m_hdc,0,0,510,320,0,0,imageWidth,imageHeight,rgbavpg,pTempBmpInfo,DIB_RGB_COLORS,SRCCOPY);
else
{       ::StretchDIBits(m_hdc,0,0,IMAGE_WIDTH,IMAGE_HEIGHT,0,0,imageWidth,imageHeight,rgbavpg,pTempBmpInfo,DIB_RGB_COLORS,SRCCOPY);
    //::SetDIBitsToDevice(m_hdc,0,0,IMAGE_WIDTH,IMAGE_HEIGHT,0,0,0,imageHeight,rgbavpg,pTempBmpInfo,DIB_RGB_COLORS);
}
::ReleaseDC(hWndDisplay[frameIndex],m_hdc);
}

请帮我解决这个问题。

尽管使用了成员变量m_hdc,但没有使用局部变量,但这段代码本身看起来不错

您是每次都看到VTune标记泄漏还是只是偶尔看到


当我看到您对IsWindow的调用和变量名g_threadMarkedForStop时,我想知道您是否在进行多线程处理。可能是因为您有时在GetDC和ReleaseDC之间破坏了窗口吗?

该片段中没有明显的漏洞。为什么m_hdc是你们班的一员?那不可能。谢谢你的回复。m_hdc是全局定义的hdc类型的句柄。你能详细解释一下为什么你认为这不可能是正确的吗?我认为汉斯的观点是,一旦你不再需要dc,就应该使用和处置dc。它们会消耗内存/资源,选择到它们中的bmp无法删除,所以让它们到处乱放通常是错误的做法。感谢您的回复。。。实际上,我的应用程序通过逐帧解码来显示一个或多个视频缩略图。VTune显示一个视频缩略图时没有泄漏,但对于多个视频缩略图,它在m_hdc=::GetDChWndDisplay[frameIndex]处显示GDIResource泄漏;甚至我也在发布它,正如你所看到的,我使用了ReleaseDC。是的,我已经完成了多线程处理来显示一个或多个缩略图。我不会破坏GetDC和ReleaseDC之间的窗口。是否有其他可能的方式释放DC?请尽快回复。感谢并感谢Mayank在这种情况下,我将1将m_hdc更改为局部变量,以确保您不会从任何地方更改m_hdc,2检查ReleaseDC的返回值,以确保Windows确实释放了DC。如果VTune在这两次更改后仍在抱怨,您可能会忽略VTune错误消息。谢谢您,Werner,我的问题现在已解决。现在我已在本地声明了m_hdc,并且它正在工作。但我仍然想问您,当我在全局声明时,GDIResource泄漏的原因是什么?再次非常感谢……我不知道。您是否在其他地方使用了m_hdc或无意中覆盖了它?如果没有,,那么我能想到的唯一原因是,你从两个线程并行调用Display,可能是因为不同的frameIndex,而一个线程只是设置了m_hdc和stretchibits,而另一个线程重写了m_hdc,因此导致第一个DC没有被释放,第二个DC被释放两次。谢谢你的回复。不,我没有使用将hdc复制到其他任何位置或覆盖它。是的,我想你是对的,它两次发布了第二个DC,第一个DC没有发布,但显示了GDIResource泄漏。谢谢你,向梅亚克问好。。。