2

キャッチされた例外を説明する素敵なウィンドウを自動的に表示する大規模なシステムを使用している場合は、メッセージとともにエラー コードを表示できると便利です (詳細な調査のために)。しかし、一部の関数呼び出しは、エラー コードを設定する失敗した Windows 関数に対するものであり、一部はエラー コードを設定しないローカルの失敗した関数であるため、最後に設定されたエラー コードが「取得されたかどうか」を確認する方法があるかどうか疑問に思います。 " すでに。

コードがあるとしましょう

if (!CopyFile(("c:\foobar.txt", "d:\foobar.txt",FALSE))
{
  throw FooBarException("bla bla bla");
}

ここで、CopyFile は失敗時にエラー コードを設定する関数であるため、エラー メッセージにエラー コードを自動的に追加することができます。ここで、エラー コードを if ステートメント内に「手動で」追加し、例外の作成時に渡されたエラー文字列に追加することができます。しかし、既存のコードの何千もの場所を変更する必要がないように、FooBarExceptionのコンストラクターでエラー コードを自動的に取得して追加することができます。しかし、これはまた問題を提起します。

エラー コードを設定しないコードによってFooBarExceptionが発生した場合はどうなりますか。次に、コンストラクターはGetLastErrorを実行しますが、現在の例外にまったく接続されていない可能性があるエラー コードを取得します。

しかし、FooBarExceptionのコンストラクターがLastErrorRetrived (または同様のもの) を呼び出して、エラー コードの追加を無視し、以前のエラーに関連していると想定する前にエラー コードが既に取得されている場合にtrueを取得できる場合。

これで、失敗してエラーコードを設定する可能性のあるすべてのWindows関数の後にエラーコードを実際に「取得」しないと、これが大騒ぎになる可能性があることを理解しています。しかし、これが完了したとしましょう。

4

2 に答える 2

2

簡単な答え: いいえ。

によって返される値はGetLastError、ロジックが付加されていない単純なグローバル (スレッドごとの) オブジェクトです。GetLastErrorSetLastErrorおよび神秘的なからアクセスできますRestoreLastError

残念ながら、ニュースを伝えなければなりません。準備が整っていないシステムにエラー処理を後付けするのは面倒です。

HRESULTいくつかの例外クラス (Win32 エラー コード、COMなど) を実装し、すべての呼び出しを変更する以外にできることはほとんどありません。

于 2013-09-17T11:31:19.187 に答える
1

GetLastError() は、スレッドの最後のエラー コード値を取得するだけで、それだけです。したがって、1回または数回呼び出されたかどうかを知る方法はないと思います。さらに、私はあなたがそうする必要はないと思います。

ここでの最善の解決策は、いくつかの基本クラス ( std::exceptionなど) から派生したWinAPIExceptionクラスを作成することです。コンストラクタWinAPIException では、他の WinAPI 呼び出しの前に GetLastError() を呼び出す必要があります。エラー値が変わらないことを保証します。

if( !CopyFile("c:\foobar.txt", "d:\foobar.txt",FALSE) )
    throw WinAPIException("Houston, we have a WINAPI problem");

WinAPI 以外の関数呼び出しの後に結果を確認する場合は、他の例外クラス (同じ基本クラスから派生) を使用してください。

if( std::cin.get() < 0 )
    throw std::runtime_error("Houston, we have runtime problem");

したがって、単一の try...catch ステートメントを使用して両方の例外をキャッチできます。

try {
    ...
} catch( std::exception &e ) {
    ...
}
于 2013-09-17T11:24:02.970 に答える