HRESULT — это тип данных компьютерного программирования , который представляет статус завершения функции .
Он используется в исходном коде приложений, ориентированных на Microsoft Windows и более ранние операционные системы IBM/Microsoft OS/2 , но его конструкция не ограничивает его использование этими средами; его можно использовать в любой системе, поддерживающей 32-разрядные целые числа .
Первоначальной целью HRESULT было создание диапазонов кодов состояния как для публичного, так и для внутреннего использования Microsoft с целью предотвращения конфликтов между кодами состояния в различных подсистемах операционной системы OS/2. [ необходима цитата ]
HRESULT одновременно представляет собой простое числовое значение и структуру полей, указывающих серьезность, объект и код состояния.
Использование HRESULT чаще всего встречается в программировании COM , где он формирует основу для стандартизированного механизма обработки ошибок , но его использование не ограничивается COM. Например, его можно использовать как альтернативу более традиционному использованию логического результата pass/fail.
HRESULT определяется в системном заголовочном файле как 32-битное целое число со знаком [1] и часто рассматривается непрозрачно как целое число, особенно в коде, который использует функцию, возвращающую HRESULT. Значение HRESULT состоит из следующих отдельных элементов:
Значение HRESULT представляет собой структуру со следующими битовыми полями : [2]
Кусочек | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Поле | С | Р | С | Н | Х | Средство | Код |
Значение HRESULT иногда отображается как шестнадцатеричное значение из 8 цифр.
Примеры: [3]
0x80070005
SRCNX<Facility-><Code---------->
, значения битового поля10000000000001110000000000000101, 0x80070005
, HRESULT в двоичном виде и HRESULT в шестнадцатеричном виде1..............................., 0x1
, S, Серьезность, отказ (1).0.............................., 0x0
, R, Зарезервировано..0............................., 0x0
, C, Клиент, Определено Microsoft (0)...0............................, 0x0
, Н, Зарезервировано....0..........................., 0x0
, Х,.....00000000111................, 0x7
, Объект: win32................0000000000000101, 0x5
, Код: E_FAULT0x80090032
0x8
- Статус: Провал0x9
- Объект: SSPI0x32
- Код: Запрос не поддерживаетсяИногда значение HRESULT отображается как целое число со знаком, но это встречается реже и его сложнее читать.
HRESULT иногда представляется как идентификатор в формате Facility_Severity_Reason : [4]
Например, STG_E_FILENOTFOUND указывает на ошибку, связанную с хранилищем: файл не существует.
Часть facility опускается, если facility равен 0 (FACILITY_NULL) или для некоторых очень распространенных значений. Например: S_OK, E_FAIL, E_INVALIDARG.
Такое представление легче читать, чем числовой формат, но оно менее точное, поскольку, несмотря на соглашение, не существует определенного алгоритма преобразования значения в имя.
Первоначально HRESULT был определен в операционной системе IBM/Microsoft OS/2 как универсальный код возврата ошибки, а затем принят в Windows NT.
Microsoft Visual Basic существенно улучшил механизмы сообщения об ошибках HRESULT, связав объект IErrorInfo с HRESULT и сохранив (указатель на) объект IErrorInfo в локальном хранилище потока. Механизм IErrorInfo позволяет программам связывать широкий спектр информации с конкретной ошибкой HRESULT: класс объекта, вызвавшего ошибку, интерфейс объекта, вызвавшего ошибку, текст ошибки и ссылку на раздел справки в файле справки. Кроме того, получатели ошибки HRESULT могут получить локализованный текст сообщения об ошибке по запросу.
Впоследствии HRESULT и связанный с ним IErrorInfo
механизм использовались в качестве механизма сообщения об ошибках по умолчанию в COM.
Поддержка механизма IErrorInfo в Windows крайне непоследовательна. Старые API Windows, как правило, вообще не поддерживают его, возвращая HRESULT без каких-либо IErrorInfo
данных. Более современные подсистемы Windows COM часто предоставляют обширную информацию об ошибках в описании сообщения объекта IErrorInfo. Более продвинутые функции механизмов ошибок IErrorInfo — ссылки на справку и локализация по требованию — используются редко.
В .NET Framework коды ошибок HRESULT/IErrorInfo преобразуются в исключения CLR при переходе от собственного кода к управляемому; а исключения CLR преобразуются в коды ошибок HRESULT/IErrorInfo при переходе от управляемого кода к собственному COM- коду.
Поскольку HRESULT определяется как целое число со знаком, а поле серьезности является самым значимым битом, отрицательное значение указывает на неудачу, а другие значения указывают на успех. Наиболее часто используемый код успеха — S_OK
which имеет значение 0. Однако в редких случаях функция возвращает код успеха с дополнительной информацией, например S_FALSE
which имеет значение 1.
Когда значение HRESULT отображается в шестнадцатеричном формате (обычно для целей отладки), разработчик может определить значение как указывающее на сбой, если оно начинается с цифры 8 или больше в 8-м и самом значимом месте. Обратите внимание, что если не дополнить его до 8 цифр ведущими нулями, значение может ошибочно рассматриваться как сбой. Например, 80005 — это успех, даже если оно начинается с 8. Если дополнить до 8 цифр, то это станет ясно: 00080005. Это несколько надуманно, поскольку обычно успех — это 0, что явно является кодом успеха.
Программные способы проверки статуса сбоя — это проверка на отрицательность или использование системного макроса. [5]
HRESULT hr = функция(...);если (hr < 0); // не удалосьесли (hr >= 0); // успешноесли (FAILED(hr)) ; // не удалосьесли (SUCCEEDED(hr)) ; // успешно
Тестирование на 0, например, (hr)
или (!hr)
будет работать в большинстве случаев, но некорректно для редко используемых кодов успеха, отличных от S_OK
таких как S_FALSE
.
Чтобы получить кодовую часть HRESULT, используйте HRESULT_CODE()
макрос.
Используйте инструмент ERR.EXE для перевода значения в соответствующий текст сообщения.
Инструмент ERRLOOK.EXE может использоваться для отображения строк ошибок, связанных с заданным значением HRESULT. Его можно запустить из командной строки Visual Studio .
Win32 SetErrorInfo
связывает значение HRESULT с соответствующим IErrorInfo
объектом. GetErrorInfo
считывает эту информацию.
Win32 FormatMessage можно использовать для получения понятного человеку описания некоторых значений HRESULT, отличных от IErrorInfo.
Заголовочный winerror.h
файл определяет некоторые часто используемые значения HRESULT. Значения HRESULT иногда кодируются в заголовочных файлах (.h) подсистемы. Эти значения также определяются в соответствующих заголовочных файлах Microsoft Windows Platforms SDK или DDK.
Название HRESULT, по-видимому, означает «дескриптор результата», поскольку многие другие типы Windows используют H для обозначения дескриптора. Например, HMODULE — это дескриптор модуля, что означает, что значение HMODULE ссылается на ресурс модуля. Однако значение HRESULT не ссылается на ресурс, поэтому оно не является дескриптором. По словам Рэймонда Чена, «в старые времена это был действительно дескриптор объекта, который содержал подробную информацию об ошибках... Команда COM решила, что соотношение затрат и выгод просто не стоит того, поэтому HRESULT превратился в простое число. Но название прижилось». [6]