C++ DirectX9中的访问冲突
最简单的方法是:每当我运行代码时,它都会抛出一个访问冲突错误。我得出结论,这是调用函数C++ DirectX9中的访问冲突,c++,directx,access-violation,C++,Directx,Access Violation,最简单的方法是:每当我运行代码时,它都会抛出一个访问冲突错误。我得出结论,这是调用函数System::renderFrame()内部的this->d3ddev.(无论什么)的错误。此函数从第112行开始。如果有人能帮我,那就太好了。 (顺便说一句,我已经开始工作了,但是我想把这段代码放到类中,这就是我开始遇到麻烦的地方。另外,我以前被告知要确保初始化所有指针。它们是通过d3d->createDevice()初始化的。) 系统.h #ifndef SYSTEM_H #define SYSTEM_H
System::renderFrame()
内部的this->d3ddev.(无论什么)
的错误。此函数从第112行开始。如果有人能帮我,那就太好了。
(顺便说一句,我已经开始工作了,但是我想把这段代码放到类中,这就是我开始遇到麻烦的地方。另外,我以前被告知要确保初始化所有指针。它们是通过d3d->createDevice()
初始化的。)
系统.h
#ifndef SYSTEM_H
#define SYSTEM_H
#include "stdinc.h"
class System {
private:
void initD3D (void);
void cleanD3D (void);
void setUpHWND (HINSTANCE, LPSTR, int);
static LRESULT CALLBACK StaticWindowProc(HWND, UINT, WPARAM, LPARAM);
LRESULT WindowProc(HWND, UINT, WPARAM, LPARAM);
HWND window;
WNDCLASSEX windowClass;
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
D3DPRESENT_PARAMETERS d3dpp;
HINSTANCE hInstance;
LPSTR lpCmdLine;
int nCmdShow;
public:
System (void);
System (HINSTANCE, LPSTR, int);
System (const System&);
~System (void);
void renderFrame (void);
};
#endif
system.cpp
#include "system.h"
//////////////////////////////////////////////////
// Class: System
// Private
//////////////////////////////////////////////////
void System::initD3D (void) {
this->d3d = Direct3DCreate9(D3D_SDK_VERSION);
ZeroMemory(&(this->d3dpp), sizeof(d3dpp));
this->d3dpp.Windowed = WINDOWED;
this->d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
this->d3dpp.hDeviceWindow = this->window;
this->d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
this->d3dpp.BackBufferWidth = SCREEN_WIDTH;
this->d3dpp.BackBufferHeight = SCREEN_HEIGHT;
this->d3dpp.EnableAutoDepthStencil = TRUE;
this->d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
this->d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
this->window,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&(this->d3dpp),
&(this->d3ddev));
this->d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE);
this->d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
this->d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);
};
void System::cleanD3D (void) {
this->d3d->Release();
this->d3ddev->Release();
};
void System::setUpHWND (
HINSTANCE hInstance,
LPSTR lpCmdLine,
int nCmdShow) {
this->hInstance = hInstance;
this->lpCmdLine = lpCmdLine;
this->nCmdShow = nCmdShow;
ZeroMemory(&(this->windowClass), sizeof(WNDCLASSEX));
this->windowClass.cbSize = sizeof(WNDCLASSEX);
this->windowClass.style = CS_HREDRAW | CS_VREDRAW;
this->windowClass.lpfnWndProc = System::StaticWindowProc;
this->windowClass.hInstance = this->hInstance;
this->windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
this->windowClass.lpszClassName = "WindowClass";
RegisterClassEx(&(this->windowClass));
this->window = CreateWindowEx(NULL, "WindowClass", "The Direct3D Program",
WS_OVERLAPPEDWINDOW, SCREEN_X, SCREEN_Y, SCREEN_WIDTH, SCREEN_HEIGHT,
NULL, NULL, this->hInstance, NULL);
};
LRESULT CALLBACK System::StaticWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
System *SystemPtr = (System*)GetWindowLong(hWnd, GWLP_USERDATA);
if(SystemPtr)
{
return SystemPtr->WindowProc(hWnd, message, wParam, lParam);
}
else
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
};
LRESULT System::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);
};
//////////////////////////////////////////////////
// Class: System
// Public
//////////////////////////////////////////////////
System::System (void) {
};
System::System (
HINSTANCE hInstance,
LPSTR lpCmdLine,
int nCmdShow) {
this->setUpHWND(hInstance, lpCmdLine, nCmdShow);
ShowWindow(this->window, this->nCmdShow);
this->initD3D();
};
System::System (const System &) {
};
System::~System (void) {
this->cleanD3D();
};
void System::renderFrame (void) {
// Update the camera here
// Update objects
// Clear objects
// FOR SOME REASON THERE IS AN ERROR HERE
this->d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 255, 0), 1.0f, 0);
this->d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
this->d3ddev->BeginScene();
// Draw objects
// Finish up
this->d3ddev->EndScene();
this->d3ddev->Present(NULL, NULL, NULL, NULL);
};
main.cpp
#include "system.h"
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow) {
System MainSys;
MainSys = System(hInstance, lpCmdLine, nCmdShow);
// Enter the main loop
MSG msg;
while (TRUE)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (msg.message == WM_QUIT)
break;
MainSys.renderFrame();
}
// Clean up DirectX and the COM
//delete MainSys;
return msg.wParam;
};
我看这里没有什么不对劲的地方,但很容易错过一些东西。 我建议检查每个D3DAPI调用的HRESULT,以确保没有失败,并将assert(pointer!=NULL)分配到所有位置,以尝试捕获问题。或者使用调试器逐步执行并查看变量以确定何时开始失败
此外,如果您还没有这样做,请打开d3d9调试版本并查看日志。它经常告诉你你错过了什么。我看这里没有什么不对劲的地方,但很容易错过什么。 我建议检查每个D3DAPI调用的HRESULT,以确保没有失败,并将assert(pointer!=NULL)分配到所有位置,以尝试捕获问题。或者使用调试器逐步执行并查看变量以确定何时开始失败
此外,如果您还没有这样做,请打开d3d9调试版本并查看日志。它通常会告诉您错过了什么。我试图编译您的代码,并更改了以下几行:
System MainSys;
MainSys = System(hInstance, lpCmdLine, nCmdShow);
进入
它成功了
我承认我不知道它失败的确切原因,但是在您的系统类中有很多东西,您正在构建它的两个实例(两行中都有一个),然后将一个实例分配给另一个实例。无论如何,这不是一个好主意,也没有必要。我猜这与Direct3D引用计数有关,当类被复制到第二行的MainSys时,您就不尊重它了
编辑
我刚刚注意到MainSys的析构函数是在用System(hInstance、lpCmdLine、nCmdShow)构造类之后被调用的;因此,刚刚获得的设备再次被释放()。我试图编译您的代码,并更改了以下行:
System MainSys;
MainSys = System(hInstance, lpCmdLine, nCmdShow);
进入
它成功了
我承认我不知道它失败的确切原因,但是在您的系统类中有很多东西,您正在构建它的两个实例(两行中都有一个),然后将一个实例分配给另一个实例。无论如何,这不是一个好主意,也没有必要。我猜这与Direct3D引用计数有关,当类被复制到第二行的MainSys时,您就不尊重它了
编辑
我刚刚注意到MainSys的析构函数是在用System(hInstance、lpCmdLine、nCmdShow)构造类之后被调用的;因此,刚刚获得的设备再次被释放。我不确定这是否是您的意思,但他构造了它的两个独立实例,然后将一个实例分配给另一个实例。您的答案听起来像是同一对象上的构造函数被调用了两次,这是不正确的。无论如何,如果这解决了问题,听起来好像违反了三条规则。非常感谢。这已经困扰了我好几天了,事情就这么简单。我不确定这是否是你的意思,但他构建了两个独立的实例,然后将一个分配给另一个。您的答案听起来像是同一对象上的构造函数被调用了两次,这是不正确的。无论如何,如果这解决了问题,听起来好像违反了三条规则。非常感谢。这已经困扰了我好几天了,事情就这么简单。