我在用 DIrectX9 编写小游戏时遇到了一些问题。我遇到了一个未处理的异常,在许多尝试中我似乎无法修复它。我将不胜感激有关此问题的一些见解。我使用了调试器,我只是不知道如何修复异常。
输出:AACF.exe 中 0x00061afd 处的未处理异常:0xC0000005:访问冲突读取位置 0x00000000。
似乎“数据”结构中的数据都等于0x00000000;我将如何解决这个问题?
System.cpp 中对异常进行了注释。
异常位置文件:
// System.cpp //
#include "Core.h"
struct {
    LPDIRECT3D9 D3D;
    LPDIRECT3DDEVICE9 D3DDEV;
    LPD3DXSPRITE D3DSPT;
    LPD3DXFONT DXFONT;
    LPDIRECT3DTEXTURE9 DisplayTexture;
} Data;
void System::InitD3D(bool Windowed, int ScreenW, int ScreenH) {
    Data.D3D = Direct3DCreate9(D3D_SDK_VERSION);
    D3DPRESENT_PARAMETERS D3DPP;
    ZeroMemory(&D3DPP, sizeof(D3DPP));
    D3DPP.Windowed = Windowed;
    D3DPP.SwapEffect = D3DSWAPEFFECT_DISCARD;
    D3DPP.hDeviceWindow = hWnd;
    D3DPP.BackBufferFormat = D3DFMT_X8R8G8B8;
    D3DPP.BackBufferWidth = ScreenW;
    D3DPP.BackBufferHeight = ScreenH;
    D3DPP.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    Data.D3D->CreateDevice(D3DADAPTER_DEFAULT,
                      D3DDEVTYPE_HAL,
                      hWnd,
                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                      &D3DPP,
                      &Data.D3DDEV);
    D3DXCreateSprite(Data.D3DDEV, &Data.D3DSPT);
    Load_Display();
    return;
}
void System::Render_Frame(void) {
    // EXCEPTIONS START HERE
    // Data.D3DDEV->Clear gives an exception
    Data.D3DDEV->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0F, 0); // Exception line
    Data.D3DDEV->BeginScene();
    Data.D3DSPT->Begin(D3DXSPRITE_ALPHABLEND);
    Draw_Display();
    Data.D3DSPT->End();
    Data.D3DDEV->EndScene();
    Data.D3DDEV->Present(NULL, NULL, NULL, NULL);
    return;
}
void System::CleanD3D() {
    Data.DisplayTexture->Release();
    Data.D3DDEV->Release();
    Data.D3D->Release();
    return;
}
void System::Load_Display() {
    LoadTexture(&Data.DisplayTexture, L"DisplaySprites.png");
    D3DXCreateFont(Data.D3DDEV, 20, 0, FW_BOLD, 1, false, DEFAULT_CHARSET,
                   OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
                   L"Arial", &Data.DXFONT);
    return;
}
void System::Draw_Display() {
    return;
}
void System::LoadTexture(LPDIRECT3DTEXTURE9* Texture, LPCTSTR FileName) {
    D3DXCreateTextureFromFileEx(Data.D3DDEV, FileName, D3DX_DEFAULT, D3DX_DEFAULT,
                                D3DX_DEFAULT, NULL, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT,
                                D3DX_DEFAULT, D3DCOLOR_XRGB(255, 0, 255), NULL, NULL, Texture);
    return;
}
void System::DrawTexture(LPDIRECT3DTEXTURE9 Texture, RECT TexCoords, float X, float Y, int A) {
    D3DXVECTOR3 Center(0.0F, 0.0F, 0.0F), Position(X, Y, 0.0F);
    Data.D3DSPT->Draw(Texture, &TexCoords, &Center, &Position, D3DCOLOR_ARGB(A,255,255,255));
    return;
}
void System::DrawString(const char* Text, int Count, RECT Rect, float X, float Y, int A, int R, int G, int B) {
    SetRect(&Rect, 0, 0, (int)X, (int)Y);
    Data.DXFONT->DrawTextA(NULL,
                      Text,
                      Count,
                      &Rect,
                      DT_BOTTOM | DT_RIGHT,
                      D3DCOLOR_ARGB(A, R, G, B));
}
void System::DrawNumber(int SetValue, RECT Rect, float X, float Y, int A, int R, int G, int B) {
    SetRect(&Rect, 0, 0, (int)X, (int)Y);
    static char Number[10];
    _itoa_s(SetValue, Number, 10);
    Data.DXFONT->DrawTextA(NULL,
                       (LPCSTR)&Number,
                       strlen((LPCSTR)&Number),
                       &Rect,
                       DT_BOTTOM | DT_RIGHT,
                       D3DCOLOR_ARGB(A, R, G, B));
}
System.cpp 头文件:
// System.h //
// Include Guard //
#ifndef _SYSTEM_H
#define _SYSTEM_H
#include "Core.h"
// Globalizing Data Structure
struct Data;
// Define screen resolution and keyboard macros
#define SCREEN_WIDTH    (1000)
#define SCREEN_HEIGHT   (700)
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
// WinProc ProtoType
LRESULT CALLBACK WindowProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
class System {
private:
    HWND hWnd;
public:
    System() {};
    void InitD3D(bool Windowed, int ScreenW, int ScreenH);
    void Render_Frame(void);
    void CleanD3D(void);
    void Load_Display();
    void Draw_Display();
    void LoadTexture(LPDIRECT3DTEXTURE9* Texture, LPCTSTR FileName);
    void DrawTexture(LPDIRECT3DTEXTURE9 Texture, RECT TexCoords, float X, float Y, int A);
    void DrawString(const char* Text, int Count, RECT Rect, float X, float Y, int A, int R, int G, int B);
    void DrawNumber(int SetValue, RECT Rect, float X, float Y, int A, int R, int G, int B);
};
#endif
其它文件:
// Core.h //
// Include Guard //
#ifndef _CORE_H
#define _CORE_H
// Pragma Comments
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
// External Include <> //
#include <Windows.h>
#include <WindowsX.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <vector>
#include <map>
#include <iostream>
#include <tchar.h>
// Internal Incldue "" //
#include "System.h"
#endif
// Core.cpp //
#include "Core.h"
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow) {
    System Sys;
    HWND hWnd;
    WNDCLASSEX WC;
    ZeroMemory(&WC, sizeof(WNDCLASSEX));
    WC.cbSize = sizeof(WNDCLASSEX);
    WC.style = CS_HREDRAW | CS_VREDRAW;
    WC.lpfnWndProc = (WNDPROC)WindowProc;
    WC.hInstance = hInstance;
    WC.hCursor = LoadCursor(NULL, IDC_ARROW);
    WC.lpszClassName = L"WindowClass";
    RegisterClassEx(&WC);
    hWnd = CreateWindowEx(NULL, L"WindowClass", L"Game Name",
                          WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
                          NULL, NULL, hInstance, NULL);
    ShowWindow(hWnd, nCmdShow);
    // Set up Direct3D
    Sys.InitD3D(TRUE, SCREEN_WIDTH, SCREEN_HEIGHT);
    // Enter Main Loop
    MSG Msg;
    while(TRUE) {
        DWORD Starting_Point = GetTickCount();
        if(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) {
            if(Msg.message == WM_QUIT)
                break;
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }
        Sys.Render_Frame();
        // Check escape key
        if(KEY_DOWN(VK_ESCAPE))
            PostMessage(hWnd, WM_DESTROY, 0, 0);
        while((GetTickCount() - Starting_Point) < 25);
    }
    Sys.CleanD3D();
    return Msg.wParam;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
    switch(Message) {
    case WM_DESTROY:
        {
            PostQuitMessage(0);
            return 0;
        } break;
    }
    return DefWindowProc(hWnd, Message, wParam, lParam);
}
bool CheckCollision(float Ax, float Ay, float Aw, float Ah, float Bx, float By, float Bw, float Bh) {
    if(Ay+Ah < By) return false;
    else if(Ay > By+Bh) return false;
    else if(Ax+Aw < Bx) return false;
    else if(Ax > Bx+Bw) return false;
    return true;
}