Я получаю (для меня) странную ошибку нарушения прав доступа во время выполнения. У меня есть класс GUI, который содержит необработанный указатель на экземпляр другого класса, Crosshair. Однако, когда я пытаюсь получить доступ к этому указателю, я получаю ошибку времени выполнения! Я говорю о доступе к указателю, мне даже не нужно разыменовывать его, чтобы получить ошибку.
Вот ошибка:
Unhandled exception at 0x00d4c486 in GPEngine.exe: 0xC0000005: Access violation reading location 0x00000004.
Ошибка возвращается к этой строке: int a = (int)m_pCrosshair;
Которая находится в методе GUI::Draw()
, указанном ниже.
РЕДАКТИРОВАТЬ:
Я нашел проблему. Это произошло в коде, который я скрывал от вас, ребята, пытаясь скрыть как можно больше ненужного кода... Проблема заключалась в следующем:
bool PsychoBots_Game::InitGame()
{
//more code...
return true;
//////GUI
GUIOnIntialisationInfo GUIdesc;
GUIdesc.pContentManager = m_pContentManager;
GUIdesc.pDevice = m_pLevel->GetDevice();
m_pGUI = new GUI(GUIdesc);
}
Чистая глупость, другими словами... Извините за это! Я не писал первую часть этого метода, поэтому я не знал о возвращаемых значениях, так как я никогда не использую его при инициализации своих собственных вещей...
Старый:
Код:
Перекрестие.h
#pragma once
#include "D3DUtil.h"
class ContentManager;
class RenderContext;
class Crosshair
{
public:
Crosshair(ID3D10Device* pDevice, ContentManager *pContentManager);
virtual ~Crosshair();
void Draw(ID3D10Device* pDevice, int clientWidth, int clientHeight);
private:
ID3D10InputLayout* m_pVertexLayout;
ID3D10Buffer* m_pVertexBuffer;
ID3D10Effect* m_pDefaultEffect;
ID3D10EffectTechnique* m_pDefaultTechnique;
ID3D10EffectMatrixVariable* m_pWVPVariable;
ID3D10EffectShaderResourceVariable* m_pDiffuseMapVariabele;
ID3D10ShaderResourceView * m_pTextureRV;
private:
//disabled
Crosshair(const Crosshair& b);
Crosshair& operator= (const Crosshair& b);
};
Crosshair.cpp
#include "stdafx.h"
#include "Crosshair.h"
#include "ContentManager.h"
#include "RenderContext.h"
#include "vertex.h"
Crosshair::Crosshair(ID3D10Device* pDevice, ContentManager *pContentManager)
:m_pVertexLayout(nullptr)
,m_pVertexBuffer(nullptr)
,m_pDefaultEffect(nullptr)
,m_pDefaultTechnique(nullptr)
,m_pWVPVariable(nullptr)
,m_pDiffuseMapVariabele(nullptr)
,m_pTextureRV(nullptr)
{
//////Load Texture
m_pTextureRV = pContentManager->GetTexture(pDevice, _T("GUI/Crosshair.png"));
//////Load Effect & Technique
m_pDefaultEffect = pContentManager->GetEffect(pDevice, _T("Effect/Texture2D.fx"));
//get technique
m_pDefaultTechnique = m_pDefaultEffect->GetTechniqueByIndex(0);
if(!m_pDefaultTechnique->IsValid())
{
MessageBox(0,_T("Technique not valid"),_T("ERROR"),0);
exit(-1);
}
//////Get Effect Variables
m_pDiffuseMapVariabele = m_pDefaultEffect->GetVariableBySemantic("DiffuseMap")->AsShaderResource();
if(!m_pDiffuseMapVariabele->IsValid()) {
MessageBox(0,_T("Getting EffectVariable m_pDiffuseMapVariabele Failed"),_T("ERROR"),0);
exit(-1);
}
m_pWVPVariable = m_pDefaultEffect->GetVariableBySemantic("WVP")->AsMatrix();
if(!m_pWVPVariable->IsValid()) {
MessageBox(0,_T("Getting EffectVariable m_pWVPVariable Failed"),_T("ERROR"),0);
exit(-1);
}
//////Define InputLayout
D3D10_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 }
};
UINT numElements = sizeof(layout)/sizeof(layout[0]);
// Create the input layout
D3D10_PASS_DESC PassDesc;
// Get the pass decriptor from the effect technique
m_pDefaultTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
HR(pDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, &m_pVertexLayout ));
//////Build Vertexbuffer
VertexPosTex v[4];
v[0].pos = D3DXVECTOR3(-0.5f, -0.5f, 0.0f); v[0].tex.x = 0.0f; v[0].tex.y = 1.0f;
v[1].pos = D3DXVECTOR3(-0.5f, 0.5f, 0.0f); v[1].tex.x = 0.0f; v[1].tex.y = 0.0f;
v[2].pos = D3DXVECTOR3( 0.5f, -0.5f, 0.0f); v[2].tex.x = 1.0f; v[2].tex.y = 1.0f;
v[3].pos = D3DXVECTOR3( 0.5f, 0.5f, 0.0f); v[3].tex.x = 1.0f; v[3].tex.y = 0.0f;
//fill a buffer description to copy the vertexdata into graphics memory
D3D10_BUFFER_DESC bd = {};
bd.Usage = D3D10_USAGE_DEFAULT;
bd.ByteWidth = sizeof( VertexPosTex ) * sizeof(v);
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA initData;
initData.pSysMem = v;
//create a ID3D10Buffer in graphics memory containing the vertex info
HR(pDevice->CreateBuffer( &bd, &initData, &m_pVertexBuffer ));
}
Crosshair::~Crosshair()
{
m_pVertexLayout->Release();
m_pVertexBuffer->Release();
}
void Crosshair::Draw(ID3D10Device* pDevice, int clientWidth, int clientHeight)
{
//////Set the input layout
pDevice->IASetInputLayout( m_pVertexLayout );
//more code...
}
GUI.h
#pragma once
#include "D3DUtil.h"
#include "GUIOnInitialisationInfo.h"
#include "GUIPerFrameInfo.h"
#include "GUIPerTickInfo.h"
#include "Crosshair.h"
class GUI
{
public:
virtual ~GUI();
GUI(const GUIOnIntialisationInfo& info);
void Tick(const GUIPerTickInfo& info);
void Draw(const GUIPerFrameInfo& info);
private:
Crosshair* m_pCrosshair;
};
GUI.cpp
#include "stdafx.h"
#include "GUI.h"
GUI::GUI(const GUIOnIntialisationInfo& info)
:m_pCrosshair(new Crosshair(info.pDevice, info.pContentManager))
{
}
GUI::~GUI()
{
delete m_pCrosshair;
}
void GUI::Tick(const GUIPerTickInfo& info)
{
}
void GUI::Draw(const GUIPerFrameInfo& info)
{
int a = (int)m_pCrosshair;
m_pCrosshair->Draw(info.pDevice, info.clientWidth, info.clientHeight);
}
Ошибка возвращается в эту строку: int a = (int)m_pCrosshair;
Когда я удалю эту строку: она прервется на m_pCrosshair->Draw(info.pDevice, info.clientWidth,info.clientHeight);
С ошибкой: Unhandled exception at 0x001fc49a in GPEngine.exe: 0xC0000005: Access violation reading location 0x00000004
Вот как создается экземпляр GUI в моем приложении:
class PsychoBots_Game : public D3DApp
{
//more code...
private:
GUI* m_pGUI;
//more code...
};
(пожалуйста, не спрашивайте меня, зачем мне метод InitGame(), мы должны сделать это, чтобы наши учителя были счастливы [смеется])
bool PsychoBots_Game::InitGame()
{
//////GUI
GUIOnIntialisationInfo GUIdesc;
GUIdesc.pContentManager = m_pContentManager;
GUIdesc.pDevice = m_pLevel->GetDevice();
m_pGUI = new GUI(GUIdesc);
}
И, наконец, WinMain:
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
TCHAR* cmdLine, int showCmd)
{
PsychoBots_Game *pGameApp= new PsychoBots_Game(hInstance);
if(pGameApp->InitApp())pGameApp->Run();
delete pGameApp;
}
Кто-нибудь может сказать мне, в чем причина проблемы? Если вам все еще нужно больше кода, просто спросите в комментарии :)
Спасибо
printf("m_pContentManager = %p\n", m_pContentManager);
перед ошибочной строкой, чтобы проверить, является ли это допустимым указателем (ошибка указывает, что он равен NULL) - person Niklas B.   schedule 02.01.2012printf("m_pCrosshair = %p\n", m_pCrosshair);
в качестве первой строки в GUI::Draw(), но когда я пытаюсь запустить код, он выдает ошибку останова! (помните, к m_pCrosshair даже нельзя получить доступ по какой-то причине), по крайней мере, не в методе Draw(), попробую в конструкторе, сек. - person xcrypt   schedule 02.01.2012printf("this = %p\n", this);
Должен напечататьNULL
. Это означает, что вы вызываете метод-членDraw
для объектаNULL
. - person Niklas B.   schedule 02.01.2012