Мой COM-сервер, реализованный в Visual C ++, использует массу другого кода C ++. Этот другой код C ++ иногда оборачивает код в __try
—__except
и переводит структурированные исключения в пользовательские исключения C ++. Эту часть я не могу изменить.
Ни один метод моего COM-сервера не должен позволять этим исключениям распространяться через границу COM, поэтому он должен перехватывать и переводить их в HRESULT
s. Эти пользовательские исключения C ++ содержат исходный код ошибки, полученный во время перевода — это что-то вроде EXCEPTION_ACCESS_VIOLATION
, Вопрос в том, как я создаю соответствующий HRESULT
значение, чтобы клиент имел как можно больше информации о том, что произошло (и, возможно, решил перезапустить сервер (и себя в случае inproc) после обнаружения нарушения доступа).
Предположим, это было EXCEPTION_ACCESS_VIOLATION
который определен в WinBase.h
#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION
и последний определяется в WinNT.h
#define STATUS_ACCESS_VIOLATION ((DWORD)0xC0000005L)
Я мог бы использовать HRESULT_FROM_WIN32()
перевести этот код в HRESULT
при условии, что это было ошибка Win32 на первом месте.
Я использую HRESULT_FROM_WIN32()
здесь или я использую любой другой способ сделать перевод?
Вы должны вернуться HRESULT
код, где вы выбираете соответствующий код, чтобы указать статус операции. Это не обязательно должен быть код ошибки, но обычно вы хотите показать что-то, что удовлетворяет FAILED(...)
макрос, например E_FAIL
, или же DISP_E_EXCEPTION
или же HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION)
,
Маловероятно, что вызывающие абоненты сравниваются с конкретными исключениями, связанными HRESULT
, поэтому конкретный код ошибки имеет смысл скорее для диагностики. Кроме того, поскольку вы завершаете обработку исключения перед выходом из метода COM, нет необходимости возвращать определенный HRESULT
код, потому что никаких дополнительных действий не требуется или необходимо.
Чтобы предоставить дополнительную информацию, можно использовать ISupportErrorInfo
, IErrorInfo
и друзья. Вызывающие абоненты могут извлекать для этого произвольное текстовое описание и многие популярные среды автоматически, например, вызывающая сторона .NET будет получать эту дополнительную информацию о сообщении об исключении, а не о стандартном сообщении, созданном из HRESULT
код.
ATL предлагает AtlReportError
обернуть SetErrorInfo
API, который также предлагает на генерации HRESULT
код:
… Если
hRes
ноль, то первые четыре версииAtlReportError
вернутьDISP_E_EXCEPTION
, Последние две версии возвращают результат макросаMAKE_HRESULT( 1, FACILITY_ITF, nID )
,