#ifdef _USING_DEBUGGER
__stdcall какаято функция
#elif
throw(какойто эксепшн)
#endif
Дебагер не дебажит. Visual studio 2008 VS Std
Пришло делать релиз и запускать ехе-шник. Неожиданно был брошен мне в лицо необработаный эксепшн. Место, где он вылазит - вызов vector:: push_back(<type> Item) в методе класса С_mesh
try-catch его не ловит, эксепшн всеравно есть
Собственно вопросы: насущный - что где и каак покрутить, чтобы заставить экзешник работать,и философский - зачем нужны конструкции типа
Код:
собственно мой код:
Код:
HRESULT C_Mesh::AddFrame(WORD ftype,TFrame* Frm)
{
try
{
TransFrames.push_back(*Frm); // тут и появляется эксепшн
}
catch(...)
{
MessageBox(NULL,
"Ошибка при добавлении кадра","err1",MB_OK);
return S_FALSE;
}
return S_OK;
};
{
try
{
TransFrames.push_back(*Frm); // тут и появляется эксепшн
}
catch(...)
{
MessageBox(NULL,
"Ошибка при добавлении кадра","err1",MB_OK);
return S_FALSE;
}
return S_OK;
};
Описания:
Код:
struct T_Frame
{
DWORD Time;
FLOAT Value;
D3DXVECTOR3 Pos;
}
class C_Mesh()
{private:
//*****
vector<T_Frame> TransFrames;
//*****
public:
HRESULT AddFrame(TFrame* Frm);
};
{
DWORD Time;
FLOAT Value;
D3DXVECTOR3 Pos;
}
class C_Mesh()
{private:
//*****
vector<T_Frame> TransFrames;
//*****
public:
HRESULT AddFrame(TFrame* Frm);
};
Код:
ну и наконец вызов:
{TFrame tmpFrame;
//******
//читаем с помощью dread из файла в tmpFrame
//******
NewObj->AddFrame(&tmpFrame);
}
{TFrame tmpFrame;
//******
//читаем с помощью dread из файла в tmpFrame
//******
NewObj->AddFrame(&tmpFrame);
}
До сдачи осталось не так много времени, и я не знаю как мне быть.
Варианты типа запускать из дебагера или написать свой Vector конечно очевидны, но они меня не устраивают
Код:
TransFrames.push_back(*Frm); // тут и появляется эксепшн
если try/catch его не перехватывает?
на функцию vector::size(). очевидно, что если эксепшн вызывается вектором, то чтото не так именно с ним.
просто усыпал код MessageBox-ами, где есть вектора, и нашел место.
Очевидно что затея была безполезной.
Просто я даже не догадывался, что в пустой вектор нельзя добавить элемент с помощью Push_Back, вернее говоря можно, но работать такая конструкция не станет.
Решил трабл с помощью vector::reserve()
Теперь появилось новое место. Привожу:
Мэйн с циклом обработки, Application мой класс, объявленный через extern
Код:
#include "main.h"
C_Application* Application;
HINSTANCE ApplicInstance;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,LPSTR lpcmdline,int nCmdShow)
{
MSG Message;
Application = new(C_Application);
ApplicInstance=hInstance;
while (true)
{
if(PeekMessage(&Message,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
if (Application->CheckDevice()) //тут появляется эксепшн.
if (!Application->CalcFrame())
Application->RenderFrame();
}
};
C_Application* Application;
HINSTANCE ApplicInstance;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,LPSTR lpcmdline,int nCmdShow)
{
MSG Message;
Application = new(C_Application);
ApplicInstance=hInstance;
while (true)
{
if(PeekMessage(&Message,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
if (Application->CheckDevice()) //тут появляется эксепшн.
if (!Application->CalcFrame())
Application->RenderFrame();
}
};
реализация C_Application::CheckDevice()
Код:
{ if (D3DDevice==NULL)return false;
switch(D3DDevice->TestCooperativeLevel())
{
case D3DERR_DEVICELOST:
return false;
case D3DERR_DEVICENOTRESET:
{
if(FAILED(D3DDevice->Reset(&D3DParameters)))
{
MessageBox(MainWindowHandle,
"Reset() failed!",
"CheckDevice()",
MB_OK);
return false;
}
InitD3D();
return true;
}
default:
return true;
}
};
switch(D3DDevice->TestCooperativeLevel())
{
case D3DERR_DEVICELOST:
return false;
case D3DERR_DEVICENOTRESET:
{
if(FAILED(D3DDevice->Reset(&D3DParameters)))
{
MessageBox(MainWindowHandle,
"Reset() failed!",
"CheckDevice()",
MB_OK);
return false;
}
InitD3D();
return true;
}
default:
return true;
}
};
Объявления C_Application:
Код:
class C_Application
{public:
C_Application();
~C_Application();
HRESULT InitWindow();
HRESULT InitD3D();
BOOL CheckDevice();
inline HWND GetWinHandle()
{return FileDir;};
inline IDirect3DDevice9** GetDevice()
{return &D3DDevice;};
HRESULT PrepareScene();
HRESULT LoadScene(LPSTR FileName);
void RenderFrame();
BOOL CalcFrame();
BOOL Paused;
DWORD BaseTime;
C_Camera D3DCam;
private:
HWND MainWindowHandle;
HWND ToolPanel;
IDirect3D9 *D3DInterface;
IDirect3DDevice9* D3DDevice;
D3DPRESENT_PARAMETERS D3DParameters;
D3DDISPLAYMODE D3DMode;
D3DCOLOR BackGround;
//*****
C_Scene * MainScene;
C_Grid * Grid;
};
{public:
C_Application();
~C_Application();
HRESULT InitWindow();
HRESULT InitD3D();
BOOL CheckDevice();
inline HWND GetWinHandle()
{return FileDir;};
inline IDirect3DDevice9** GetDevice()
{return &D3DDevice;};
HRESULT PrepareScene();
HRESULT LoadScene(LPSTR FileName);
void RenderFrame();
BOOL CalcFrame();
BOOL Paused;
DWORD BaseTime;
C_Camera D3DCam;
private:
HWND MainWindowHandle;
HWND ToolPanel;
IDirect3D9 *D3DInterface;
IDirect3DDevice9* D3DDevice;
D3DPRESENT_PARAMETERS D3DParameters;
D3DDISPLAYMODE D3DMode;
D3DCOLOR BackGround;
//*****
C_Scene * MainScene;
C_Grid * Grid;
};
В этом месте выскакивает 2 эксепшна:
Read violation at 0х00000000
Write violation at 0x009*****
Первый заставляет думать, что устройство не создано или гдето что-то не объявлено, но увы все объявлено правильно и до работы с vector-ом все работает
Второй нам машет, что память, куда мы пытаемся писать - занята. Единственное НО в том, что явной записи не идет нигде.
Учитывая то, что был рецедив с strcpy которая записывалась поверх D3DDevice есть основание думать, что std::vector что-то пишет на то место, где сидят нужжные мне данные.
Собственно вопросы:
- как обезопасить мой код от таких чудесных std-шных узурпаторов?
- как добиться, чтобы ехе-шник работал также как работает внутри отладчика
- что сделать, чтобы по завершении приложения не оставалось процесса, ибо PostQuitMessage(0) внутри WM_DESTROY явно не в состоянии