Обработка исключений DirectX

0

Я следую руководству rastertek по DirectX, а также изучая Exception-Safety в Generic Components Дэвидом Абрахамом (http://www.boost.org/community/exception_safety.html).

Почему (в лучшем случае любого знания) обработка исключений настраивается так, как это делается в учебнике rastertek и какой уровень защиты он предлагает?

Например:

mhresult = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &mfeatureLevel, 1,
    D3D11_SDK_VERSION, &mswapChainDesc, &mswapChain, &mdevice, NULL, &mdeviceContext);

if (FAILED(mhresult))
{
    return false;
}

если необработанное исключение возникает при вызове CreateDevice, программа не сработает, прежде чем мы проверим результат mhresult?

Имеет ли значение, вызываем ли мы метод с возвращаемым значением HResult или просто логическим?

result = mEstablishHW();
if (!result)
{
    return false;
}

Существует ли альтернативный подход, обеспечивающий надежную защиту исключений без воздействия на производительность?

  • 0
    можешь уточнить? здесь нет обработки исключений. Также 2 примера кода функционально равны
Теги:
exception-handling
directx

2 ответа

3
Лучший ответ

DirectX - это COM -based API. И исключениям не разрешается пересекать границу COM. Поэтому нет функции DirectX, которая когда-либо бросается. Вместо этого они используют коды возврата в стиле С, которые называются HRESULT, для указания ошибок.

Чтобы эффективно работать с DirectX, очевидно, вам следует изучить хотя бы некоторые основы COM. Но вот советы для начала, чтобы сделать ваш исходный код более безопасным и упростить отладку:

  • Всегда всегда проверяйте код возврата. Это не значит, что вы должны писать if/else каждый раз. Напишите макрос, который проверит HRESULT, сломает отладчик в случае "не S_OK " и сообщит вам файл, строку и функцию, где это произошло. Вы также можете конвертировать HRESULT в читаемую строку и выводить ее (в консоли).
  • Это хорошая идея - проверить выходные объекты, если они действительны (т. mswapChain Не " NULL "): mswapChain, mdevice, mdeviceContext в вашем примере.
  • Использовать слой отладки DirectX: D3D11_CREATE_DEVICE_DEBUG
  • Используйте инструменты диагностики графики: один встроен в Visual Studio с 2012 года, Nvidia Nsight тоже очень хорош
  • Наконец, прочитайте документы! MSDN не идеальна, но документы DirectX довольно хорошо написаны.

В любом случае, DirectX не API, чтобы начать изучать безопасность исключений. Возможно, стандартная библиотека (например, попытка написать правильную функцию swap для ваших классов) или Boost (например, файловая система) будет работать лучше для этой цели.

  • 0
    Именно та информация, которую я искал, спасибо!
0

DirectX не использует исключения для сообщения об ошибках или чего-либо еще. Интерфейсы DirectX предназначены для агностики компилятора, а использование C++ исключений свяжет их использование с конкретным компилятором из-за различий ABI. Даже разные версии Microsoft C++ были бы несовместимы из-за различий ABI.

Поскольку большинство методов и функций DirectX возвращают значение HRESULT, вам нужно будет проверить наличие ошибок, как в первом примере. Затем вы можете выбросить исключение в свой собственный код, если это имеет смысл для вашего проекта.

  • 0
    Хорошо, так что я думаю, что я получил это тогда: по сути, вызов DirectX дает гарантию без бросков, верно? Правильный вызов DirectX не вызовет сбой приложения, но вместо этого вернет S_OK или FAILED. Тем не мение; игнорирование FAILED, возвращенного в ваш собственный код, потенциально может вызвать исключение, когда ваше приложение пытается перейти к следующему вызову DirectX, верно?
  • 0
    Да, вы не можете игнорировать ошибку и продолжать, как если бы вызов был успешным. В первом примере ни один из выходных параметров ( mswapChain mdevice mdeviceContext ) не будет установлен в случае сбоя, поэтому попытка использовать их после сбоя, скорее всего, приведет к сбою. Однако вы продолжаете использовать интерфейс Direct3D после сбоя, как если бы сбойная операция никогда не выполнялась. В первом примере вы можете повторить попытку с другими параметрами, если первый вызов не удался.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню