6

HRESULT の戻り値を操作しているときに、非常に厄介なことに遭遇しました。成功は 0 で、失敗は 1 のようです。この背後にあるロジックは何ですか?

私は実際に試してみif(!hr)て惨めに失敗し、実際の成功の retval が 0 であることがわかるまで、1 時間の人生を無駄にしました。この慣習に光を当てます。

4

3 に答える 3

16

HRESULT の本来の目的は、OS/2 オペレーティング システムのさまざまなサブシステムでのエラー コード間の衝突を防ぐために、エラー コードの範囲を公的および Microsoft 内部で使用するために正式にレイアウトすることでした。

そのため、値 0 (HRESULT の最上位ビット) は「エラーなし」、つまり成功を意味します。

ただし、HRESULT の最上位ビットが 0 に設定され、他のビットが 0 以外に設定される可能性があるため、注意が必要if(0 == hr) { ... }です。成功を確認する正しい方法はif(0 <= hr) { ... }.

ウィキペディアには、より詳細な情報があります。

SUCCEEDEDまた、FAILEDマクロを使用して、HRESULT 値を処理する際のミスを回避できます。if(0 <= hr) { ... }if(SUCCEEDED(hr)) { ... }基本的に同じものです。

于 2012-10-12T05:15:27.433 に答える
4

もう一度誤解しています。ほとんどすべてのシステムのすべてのシステムエラーの戻り値0は成功であり、ゼロ以外の戻り値はエラーコードを示します。この手法を使用すると、1つの戻り値でさまざまな種類のエラーを報告できます。しかし、HRESULT私たち>= 0は成功と<0エラーのために持っているので、の観点からの1の値はHRESULT、エラーではなく成功です。> 0はHRESULT機能に関する警告または情報を示し、0は絶対的な成功を意味し、<0はエラーを示します。HRESULTのレイアウトは次のとおりです。

 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+-+-+-+-+-+---------------------+-------------------------------+
|S|R|C|N|r|    Facility         |               Code            |
+-+-+-+-+-+---------------------+-------------------------------+
where
  S - Severity - indicates success/fail
      0 - Success
      1 - Fail (COERROR)
  R - reserved portion of the facility code, corresponds to NT's second severity bit.
  C - reserved portion of the facility code, corresponds to NT's C field.
  N - reserved portion of the facility code. Used to indicate a mapped NT status value.
  r - reserved portion of the facility code. Reserved for internal use. Used to 
        indicate HRESULT values that are not status values, but are instead message
        ids for display strings.
  Facility - is the facility code
  Code - is the facility's status code

ご覧のとおり、これはカスタムエラーコード、警告、および情報を非常に合理的にサポートする最高の設計の1つです。

于 2012-10-12T05:22:58.677 に答える
1

通常、SUCCEEDEDFAILEDマクロを使用してHRESULTs をテストする必要があります。これは、大部分の関数が成功に対して (値 = 0) を返しS_OKますが、ゼロ以外の成功値 ( などS_FALSE) があるためです。多くの場合、そのような値が返される可能性がある場合は明示的にテストする必要がありますが、一般的なケースでは、使用するSUCCEEDED方が明確で安全です。

if (SUCCEEDED(hr)) { // ...
于 2012-10-12T06:03:41.100 に答える