当我取消注释创建位图的一行代码时,我遇到了第一次机会异常错误。我以与我制作的其他精灵相同的方式创建了这个spritesheet BMP。错误消息是这样的:
First-chance exception at 0x004788ca in HenwayRevamped.exe: 0xC0000005: Access violation writing location 0x02224000.
我正在运行基于Michael Morrison的GameEngine课程的游戏。我已经对这个错误做了几个小时的研究,包括许多StackOverflow线程& this handy site但我仍然不确定问题是什么。这是函数调用:
// Create a bitmap from a resource
Bitmap::Bitmap(HDC hDC, UINT uiResID, HINSTANCE hInstance)
: m_hBitmap(NULL), m_iWidth(0), m_iHeight(0)
{
Create(hDC, uiResID, hInstance);
}
这是功能:
BOOL Bitmap::Create(HDC hDC, UINT uiResID, HINSTANCE hInstance)
{
// Free any previous DIB info
Free();
// Find the bitmap resource
HRSRC hResInfo = FindResource(hInstance, MAKEINTRESOURCE(uiResID), RT_BITMAP);
if (hResInfo == NULL)
return FALSE;
// Load the bitmap resource
HGLOBAL hMemBitmap = LoadResource(hInstance, hResInfo);
if (hMemBitmap == NULL)
return FALSE;
// Lock the resource and access the entire bitmap image
PBYTE pBitmapImage = (BYTE*)LockResource(hMemBitmap);
if (pBitmapImage == NULL)
{
FreeResource(hMemBitmap);
return FALSE;
}
// Store the width and height of the bitmap
BITMAPINFO* pBitmapInfo = (BITMAPINFO*)pBitmapImage;
m_iWidth = (int)pBitmapInfo->bmiHeader.biWidth;
m_iHeight = (int)pBitmapInfo->bmiHeader.biHeight;
// Get a handle to the bitmap and copy the image bits
PBYTE pBitmapBits;
m_hBitmap = CreateDIBSection(hDC, pBitmapInfo, DIB_RGB_COLORS,
(PVOID*)&pBitmapBits, NULL, 0);
if ((m_hBitmap != NULL) && (pBitmapBits != NULL))
{
const PBYTE pTempBits = pBitmapImage + pBitmapInfo->bmiHeader.biSize +
pBitmapInfo->bmiHeader.biClrUsed * sizeof(RGBQUAD);
CopyMemory(pBitmapBits, pTempBits, pBitmapInfo->bmiHeader.biSizeImage);
// Unlock and free the bitmap graphics object
UnlockResource(hMemBitmap);
FreeResource(hMemBitmap);
return TRUE;
}
// Something went wrong, so cleanup everything
UnlockResource(hMemBitmap);
FreeResource(hMemBitmap);
Free();
return FALSE;
}
此外,这是我的IDE w / Locals窗口的屏幕截图。排水沟中的绿色箭头图标指向抛出异常的行:
Image Hosted by ImageShack.us http://imageshack.us/a/img341/7678/20121216010703am.png
这是我的设备上下文是问题吗? hDC变量下的红色感叹号图标看起来可能指向问题,但它分配了一个句柄,所以我不确定。我的想法已经用完了,我转向主人。
答案 0 :(得分:2)
写入时发生访问冲突,这表明您正在超出目标缓冲区。存在许多不同类型的位图格式,因此难以计算缓冲区的正确大小。你的代码确实可以处理一些位图,所以我怀疑你对位深度,颜色表大小,对齐方式或类似的东西都有一个不好的假设。
只要你可以,你也可以让Windows完成工作:
BOOL Bitmap::Create2(UINT uiResID, HINSTANCE hInstance) {
BOOL bSuccess = FALSE;
Free();
m_hBitmap = reinterpret_cast<HBITMAP>(
::LoadImage(hInstance, MAKEINTRESOURCE(uiResID), IMAGE_BITMAP,
0, 0, LR_CREATEDIBSECTION));
if (m_hBitmap != NULL) {
BITMAP bmp;
if (::GetObject(m_hBitmap, sizeof(bmp), &bmp) == sizeof(bmp)) {
m_iWidth = bmp.bmWidth;
m_iHeight = bmp.bmHeight;
bSuccess = TRUE;
}
}
return bSuccess;
}
这适用于所有有效位图。请注意,您不再需要将句柄传递给DC。
答案 1 :(得分:0)
第一次机会异常通常不用担心,除非你改变了一些设置,否则调试器不应该停在它们上面。未处理的异常是一个实际问题,应用程序没有捕获和处理异常。
如果调试器在发生时中断,您可以更改异常设置以防止将来发生,或者您可以继续并查看它是否变为未处理的异常。
有关第一次机会与第二次机会的更多信息:http://support.microsoft.com/kb/105675
答案 2 :(得分:-1)
感谢Roman的洞察力,我能够提出这个编译和解决方案。工作正常。如果我得到更多与其他图像的异常,我将制作一个数组并迭代它,但现在可以工作:
/* This causes strange black lines at the top of some sprites. Pixel bleeding?
if(pBitmapInfo->bmiHeader.biSizeImage > neededBytes )
CopyMemory(pBitmapBits, pTempBits, neededBytes);
else
CopyMemory(pBitmapBits, pTempBits, pBitmapInfo->bmiHeader.biSizeImage);
*/
//workaround for powerup sprite
if(pBitmapInfo->bmiHeader.biSizeImage == 294914 )
CopyMemory(pBitmapBits, pTempBits, neededBytes);
else
CopyMemory(pBitmapBits, pTempBits, pBitmapInfo->bmiHeader.biSizeImage);