1

ビットマップを作成するコード行のコメントを外すと、初回例外エラーが発生します。このスプライトシート BMP は、これまでに作成した他のスプライトと同じ方法で作成しました。エラーメッセージは次のとおりです。

First-chance exception at 0x004788ca in HenwayRevamped.exe: 0xC0000005: Access violation writing location 0x02224000.

Michael Morrison の GameEngine クラスに基づいて構築されたゲームを実行しています。多くの StackOverflow スレッドとこの便利なサイトを含め、このエラーについて数時間調査しましたが、問題が何であるかはまだわかりません. 関数呼び出しは次のとおりです。

// 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のスクリーンショットです。ガターの緑色の矢印アイコンは、例外がスローされた行を指しています。

ImageShack.us がホストする画像 http://imageshack.us/a/img341/7678/20121216010703am.png

問題は私のデバイスコンテキストですか?hDC 変数の下にある赤い感嘆符アイコンは、問題を指しているように見えますが、ハンドルが割り当てられているため、よくわかりません。アイデアが尽きたので、マスターに頼っています。

4

3 に答える 3

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 にハンドルを渡す必要がなくなったことに注意してください。

于 2012-12-16T17:19:22.887 に答える
0

通常、初回例外は気にする必要はありません。また、設定を変更しない限り、デバッガーが停止することはありません。未処理の例外は実際の問題であり、アプリケーションがキャッチして処理しなかった例外がありました。

発生時にデバッガーが壊れている場合は、例外設定を変更して将来それを防ぐことができます。または、続行してハンドルされない例外になるかどうかを確認することもできます。

ファースト チャンスとセカンド チャンスの詳細については、http ://support.microsoft.com/kb/105675 をご覧ください。

于 2012-12-16T06:52:00.803 に答える
-1

ローマンの洞察力のおかげで、コンパイルして正常に動作するこの回避策を思い付くことができました。他の画像でさらに例外が発生した場合は、配列を作成して反復処理しますが、これは今のところ機能します。

/*  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);
于 2012-12-16T15:46:43.983 に答える