Schreiben eines Ausnahmefilters
Sie können eine Ausnahme behandeln, indem Sie entweder auf die Ebene des Ausnahmehandlers wechseln oder die Ausführung fortsetzen. Anstatt den Ausnahmehandlercode zum Behandeln der Ausnahme und zum Durchfallen zu verwenden, können Sie einen Filterausdruck verwenden, um das Problem zu sauber. Wenn Sie dann (-1) zurückgeben EXCEPTION_CONTINUE_EXECUTION
, können Sie den normalen Fluss fortsetzen, ohne den Stapel zu löschen.
Hinweis
Einige Ausnahmen können nicht fortgesetzt werden. Wenn der Filter für eine solche Ausnahme als -1 ausgewertet wird, löst das System eine neue Ausnahme aus. Beim Aufrufen RaiseException
bestimmen Sie, ob die Ausnahme fortgesetzt wird.
Der folgende Code verwendet beispielsweise einen Funktionsaufruf im Filterausdruck : Diese Funktion behandelt das Problem und gibt dann -1 zurück, um den normalen Kontrollfluss fortzusetzen:
// exceptions_Writing_an_Exception_Filter.cpp
#include <windows.h>
int main() {
int Eval_Exception( int );
__try {}
__except ( Eval_Exception( GetExceptionCode( ))) {
;
}
}
void ResetVars( int ) {}
int Eval_Exception ( int n_except ) {
if ( n_except != STATUS_INTEGER_OVERFLOW &&
n_except != STATUS_FLOAT_OVERFLOW ) // Pass on most exceptions
return EXCEPTION_CONTINUE_SEARCH;
// Execute some code to clean up problem
ResetVars( 0 ); // initializes data to 0
return EXCEPTION_CONTINUE_EXECUTION;
}
Es ist ratsam, einen Funktionsaufruf im Filterausdruck zu verwenden, wenn der Filter etwas Komplexes ausführen muss. Das Auswerten des Ausdrucks verursacht die Ausführung der Funktion, in diesem Fall Eval_Exception
.
Beachten Sie die Verwendung der GetExceptionCode
Ausnahme. Diese Funktion muss innerhalb des Filterausdrucks der __except
Anweisung aufgerufen werden. Eval_Exception
kann nicht aufgerufen GetExceptionCode
werden, aber es muss der Ausnahmecode an ihn übergeben werden.
Dieser Handler übergibt die Steuerung an einen anderen Handler, sofern die Ausnahme keine Ganzzahl oder ein Gleitkommaüberlauf ist. Wenn dies der Fall ist, ruft der Handler eine Funktion (ResetVars
ist nur ein Beispiel, keine API-Funktion) auf, um mehrere globale Variablen zurückzusetzen. Der __except
Anweisungsblock, der in diesem Beispiel leer ist, kann nie ausgeführt werden, weil Eval_Exception
nie (1) zurückgegeben EXCEPTION_EXECUTE_HANDLER
wird.
Die Verwendung eines Funktionsaufrufs ist ein gutes allgemeines Verfahren für die Behandlung von komplexen Filterausdrücken. Zwei andere hilfreiche Funktionen der Programmiersprache C sind:
Der bedingte Operator
Der Kommaoperator
Der bedingte Operator ist hier häufig hilfreich. Es kann verwendet werden, um nach einem bestimmten Rückgabecode zu suchen und dann einen von zwei verschiedenen Werten zurückzugeben. Beispielsweise erkennt der Filter im folgenden Code die Ausnahme nur, wenn die Ausnahme lautet STATUS_INTEGER_OVERFLOW
:
__except( GetExceptionCode() == STATUS_INTEGER_OVERFLOW ? 1 : 0 ) {
Der bedingte Operator ist in diesem Fall in erster Linie dafür verantwortlich, Klarheit zu schaffen, da der folgende Code zum gleichen Ergebnis führt:
__except( GetExceptionCode() == STATUS_INTEGER_OVERFLOW ) {
Der bedingte Operator ist in Situationen nützlicher, in denen der Filter in -1 EXCEPTION_CONTINUE_EXECUTION
ausgewertet werden soll.
Mit dem Kommaoperator können Sie mehrere Ausdrücke in Sequenz ausführen. Anschließend wird der Wert des letzten Ausdrucks zurückgegeben. Der folgenden Code speichert z. B. den Ausnahmecode in einer Variablen und testet dann auf:
__except( nCode = GetExceptionCode(), nCode == STATUS_INTEGER_OVERFLOW )
Siehe auch
Schreiben eines Ausnahmehandlers
Structured Exception Handling (C/C++)
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für