Как использовать проверку условия HRESULT в C++

HRESULT hr = S_OK; //initialization`
if (int i == 5)
{
    hr = 1; //Is it correct usage?  
}
if (hr == 1)
    cout<<"The value of i is 5";

Поскольку я всегда слышал, что HRESULT выводится в таких строках, как E_TIMEOUT и т. д., правильно ли использовать число, как я использовал.


person james    schedule 02.02.2020    source источник
comment
Это не ответ на мой вопрос. Мой вопрос в другом. Я не могу использовать случай SUCCCED или FAILED, потому что я знаю, что происходит сбой, но есть несколько кодов сбоя, и я должен использовать определенный код сбоя. Пожалуйста, прочитайте мой вопрос еще раз.   -  person james    schedule 02.02.2020
comment
Не используйте определенные жестко заданные значения часов. Используйте стандартные коды ошибок, как определено в <WinError.h>, или используйте MAKE_HRESULT для создания собственных кодов ошибок.   -  person selbie    schedule 02.02.2020
comment
HRESULT специфичен для Windows. Не делайте никаких предположений, используйте то, что говорит SDK. FAILED или SUCCEEDED или сравните его с известными значениями HRESULT.   -  person Michael Chourdakis    schedule 02.02.2020
comment
Код даже не компилируется, поэтому приведите правильный пример.   -  person Acorn    schedule 04.02.2020


Ответы (3)


По сути, все находится внутри '‹winerror.h›'. Но у меня такое чувство, что это может быть непопулярным ответом.

Контекст

HRESULT — это дескриптор (значение типа long), возвращаемый из Win32, COM и других функций в огромном океане Windows SDK. Что и как упаковано в этой ручке, объясняется в <winerror.h>

Я осмелюсь предположить, что есть один факт о Win32, очень полезный для разработчиков C++.

Win32 написана на C

Таким образом, исключений C++ нет. То же самое HRESULT — ваш друг. Существуют специальные исключения, называемые SEH (обработка структурированных исключений). И они встроены в винду. Даже MS STL использует SEH, когда исключения C++ отключены (ох!). Но это не было частью вопроса.

Использование выглядит очень просто:

HRESULT hr ;
ULONG  ansi_size_  ;
        hr = DiscpUnicodeToAnsiSize(L"Look Ma, I am doing WIN32!", &ansi_size_ );

        if ( FAILED(hr) ) {
              //  there was some error
              //  what exactly has happened?
              HRESULT facility = HRESULT_FACILITY(hr);
              HRESULT severity = HRESULT_SEVERITY(hr);
              // we can for example look for a particular facility 
              if ( facility  == FACILITY_MSMQ) 
              {
                 // hey, just what is MSMQ ?!
                 // let see the code part
                 HRESULT code = HRESULT_CODE(hr);
              }
        }

<winerror.h> (в настоящее время) состоит из 62238 строк. Не стесняйтесь просматривать его, и вы найдете много полезных самородков.

статья о HRESULT на самом деле короткая и точная.

Win32 уже несколько десятилетий. Неизбежно есть пыльные углы. Но HRESULT останется навсегда и будет активно развиваться.

Как это происходит, протокол кодов ошибок Windows, редакция 20 (вздох) ="nofollow noreferrer">был выпущен только вчера!

Но это C!?

Было выпущено несколько официальных проектов (также выпущенных) для инкапсуляции HRESULT и COM в типы C++. MFC, ATL... Мне больше всего нравится Поддержка компилятора COM и, в частности, _com_error.

Надеюсь, это помогло...

person Chef Gladiator    schedule 09.04.2021

Главный вопрос здесь в том, для чего вы используете HRESULT?

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

HRESULT используются как способ сообщить об успешном или неудачном вызове функции. Обычно HRESULT это либо S_OK (0), либо ошибка (отрицательные числа). S_FALSE (1, не провал, но и не успех) используется реже.

При использовании с COM или .NET вызывающая сторона обычно только проверяет, успешно ли выполнена функция или нет. По умолчанию при маршалинге функции, которая возвращает HRESULT, маршаллер .NET превращает функцию в функцию void, вызывая исключение, если результат отрицательный, и отбрасывая результат, если он неотрицательный.

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

person Motti    schedule 04.02.2020
comment
Хорошо сказано @Motti - person Chef Gladiator; 09.04.2021

HRESULT 0 или S_OK является стандартным кодом "успешного выполнения". Принимая во внимание, что 1 — это S_FALSE, что означает «успех, но я не совсем сделал то, что вы просили, потому что это, вероятно, уже было сделано».

Стандартный шаблон ближе к этому:

HRESULT hr = S_OK //initialization


if (int i == 5)
{
    hr = S_OK;    
}
else
{
    hr = E_INVALIDARG;  // Or any E_ error code
}

if (SUCCEEDED(hr))
{
    cout<<"The value of i is 5";
}
else if (hr == E_INVALIDARG)
{
    // handle specific error
}
else
{
   // handle all other errors generically
}
person selbie    schedule 02.02.2020
comment
В контексте WIN32 и HRESULT это не стандартный шаблон. - person Chef Gladiator; 09.04.2021