У меня есть приложение DirectX. Это очень просто, но у меня проблема с этим. Я создаю устройство, контекст устройства и т. Д., И все работает, но когда я ухожу, происходит сбой и возникает ошибка: HEAP: Free Heap block 3ad7d18 modified at 3ad7d98 after it was freed
. Это происходит, только если я вызываю функцию IDXGISwapChain Present
хотя бы один раз. Если я этого не сделаю, весь процесс очистки пройдет хорошо. Более того, я вызываю Release
на каждый объект COM, и авария ALWAYS возникает только тогда, когда я выпускаю последний COM-объект (заказ не имеет значения). Я использую DirectX 11 (Win8 SDK) на Windows 7, MS Visual 2012Сбой при очистке Приложение DirectX
Моя функция цикл сообщений:
int Engine::run(){
MSG msg = { 0 };
mTimeCounter->restart(); // doesn't matter
while(msg.message != WM_QUIT){
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
updateScene(mTimeCounter->deltaTime());
drawScene();
}
}
return static_cast<int>(msg.wParam);
}
updateScene ничего не делать сейчас, и сделать сцену только назвать это две функции:
void Engine::sceneBegin(){
static FLOAT color[] = { 0.05f, 0.15f, 0.05f, 1.0f };
mDeviceContext->ClearRenderTargetView(mBackBufferView, color);
mDeviceContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
}
void Engine::sceneEnd(){
mSwapChain->Present(0, 0); // crash do not occure if i comment this line of code
}
Часть сообщений переключения:
case WM_QUIT : // i do not receive it even once because i press window's X button and it destroy window before i could receive WM_QUIT (or not? :P)
{
DestroyWindow(mMainWnd);
}
break;
case WM_DESTROY : // i receive it if press window's X button
{
PostQuitMessage(0);
}
break;
return DefWindowProc(hWnd, msg, wParam, lParam);
Основная функция, в которой я инициализировать и начать свой Engi пе:
EngTest *eng = new EngTest();
eng->initialize(hInstance, L"Hi", show);
int r = eng->run();
delete eng; // crash occures here but only if i call Present at least once.
Shutdown:
// called in Engine's destructor
void Engine::shutdown(){
RELEASE_COM(mDepthStencilView);
RELEASE_COM(mDepthStencilBuffer);
RELEASE_COM(mBackBufferView);
RELEASE_COM(mSwapChain);
if(mDeviceContext)
mDeviceContext->ClearState();
RELEASE_COM(mDeviceContext);
RELEASE_COM(mDevice);
}
RELEASE_COM
#define RELEASE_COM(x) { if(x != NULL) { x->Release(); x = NULL; } }
Один быстрый комментарий к вашему коду процедуры окна: WM_QUIT никогда не будет обращаться к процедуре окна, поскольку он предназначен как сигнал к насосу сообщений (ваш вызов PeekMessage), что все окна программы были и что программа также должна закрыться. Ваша проверка WM_QUIT должна идти после вызова PeekMessage, но перед вызовом Translate/DispatchMessage. Вам может понадобиться WM_CLOSE, который запускается всякий раз, когда пользователь запрашивает закрыть окно (т. Е. Нажимает кнопку X или нажимает ALT + F4 или выбирает Close из меню Window). Также ваш стиль кода напоминает мне о Фрэнке Луне ... – Alex
Я думаю, что вы правы с сообщением WM_QUIT, спасибо :) Теперь это довольно старый код. Я начал использовать интеллектуальные указатели и умные указатели. И у меня есть книга Фрэнка Луны. Это для DirectX 11 и мне это нравится :) –