Grundlegende Konzepte, wenn verwaltete Ausnahmen verwendet werden
Dieses Thema erläutert Ausnahmebehandlung in verwalteten Anwendungen. Das bedeutet, eine Anwendung, die mit der /clr-Compileroption kompiliert wird.
In diesem Thema
Auslösen von Ausnahmen unter /clr
Try/catch-Blöcke für CLR-Erweiterungen
Hinweise
Wenn Sie mit der /clr - Option kompilieren, können Sie CLR-Ausnahmen sowie standardmäßige C++-Ausnahmebehandlung und strukturierte Ausnahmebehandlung (SEH) behandeln. Eine CLR-Ausnahme ist jede Ausnahme, die durch einen verwalteten Typ ausgelöst wird. Die System::Exception-Klasse stellt viele nützliche Methoden zum Verarbeiten von CLR-Ausnahmen bereit und wird als Basisklasse für benutzerdefinierte Ausnahmeklassen empfohlen.
Die Ausnahmetypen, die von einer Schnittstelle abgeleitet werden, wird unter /clr nicht unterstützt. Für die Common Language Runtime ermöglicht Sie nicht, Ausnahmen für Stapelüberläufe abzufangen; eine Stapelüberlaufausnahme beendet den Prozess.
Weitere Informationen zu Unterschieden bei der Ausnahmebehandlung in verwalteten und nicht verwalteten Anwendungen, finden Sie unter Unterschiede im Ausnahmebehandlungs-Verhaltens unter Managed Extensions for C++.
Auslösen von Ausnahmen unter /clr
Der C++-Wurfsausdruck wird erweitert, um ein Handle auf einen CLR-Typ auszulösen. Im folgenden Beispiel wird einem benutzerdefinierten Ausnahmetyp und anschließend eine Instanz dieses Typs aus:
// clr_exception_handling.cpp
// compile with: /clr /c
ref struct MyStruct: public System::Exception {
public:
int i;
};
void GlobalFunction() {
MyStruct^ pMyStruct = gcnew MyStruct;
throw pMyStruct;
}
Ein Werttyp muss geschachtelt werden, bevor ausgelöst wird:
// clr_exception_handling_2.cpp
// compile with: /clr /c
value struct MyValueStruct {
int i;
};
void GlobalFunction() {
MyValueStruct v = {11};
throw (MyValueStruct ^)v;
}
Try/catch-Blöcke für CLR-Erweiterungen
Gleiche try/catch-Blockstruktur können zum Abfangen von CLR und systemeigener Ausnahmen verwendet werden:
// clr_exception_handling_3.cpp
// compile with: /clr
using namespace System;
ref struct MyStruct : public Exception {
public:
int i;
};
struct CMyClass {
public:
double d;
};
void GlobalFunction() {
MyStruct^ pMyStruct = gcnew MyStruct;
pMyStruct->i = 11;
throw pMyStruct;
}
void GlobalFunction2() {
CMyClass c = {2.0};
throw c;
}
int main() {
for ( int i = 1; i >= 0; --i ) {
try {
if ( i == 1 )
GlobalFunction2();
if ( i == 0 )
GlobalFunction();
}
catch ( CMyClass& catchC ) {
Console::WriteLine( "In 'catch(CMyClass& catchC)'" );
Console::WriteLine( catchC.d );
}
catch ( MyStruct^ catchException ) {
Console::WriteLine( "In 'catch(MyStruct^ catchException)'" );
Console::WriteLine( catchException->i );
}
}
}
Ausgabe
In 'catch(CMyClass& catchC)'
2
In 'catch(MyStruct^ catchException)'
11
Reihenfolge der für C++-Objekte Entladung
Entladen tritt für alle C++-Objekte mit Destruktoren auf, die möglicherweise im Laufzeitkellerspeicher zwischen der auslösenden Funktion und der Behandlungsfunktion sind. Da auf CLR-Typen dem Heap zugeordnet sind, gilt beim Entladen nicht auf sie zu.
Die Reihenfolge der Ereignisse für eine Ausnahme ist, wie folgt:
Die Laufzeit ausgeführt wird den Stapel durch, die nach der entsprechenden catch-Klausel oder im Fall SEH sucht, außer für Filter SEH, um die Ausnahme abzufangen. Catch-Klauseln werden zuerst in der lexikalischen Reihenfolge und dann dynamisch die Abwärtsumwandlung Aufrufliste gefunden.
Sobald der richtige Handler, der Stapel entladen wird zu diesem Punkt gefunden. Für jeden Funktionsaufruf auf dem Stapel, werden ihre lokalen Objekte zerstört und __finally werden Blöcke ausgeführt, der nach außen geschachtelt.
Sobald wird der Stapel entladen, die catch-Klausel wird ausgeführt.
Verwaltete nicht verwalteter Typen
Wenn ein nicht verwalteter Objekttyp ausgelöst wird, wird er mit einer Ausnahme vom Typ System::Runtime.InteropServices::SEHException umschlossen. Beim Suchen für die entsprechende catch-Klausel, gibt es zwei Möglichkeiten.
Wenn ein systemeigenes C++-Typ erreicht wird, wird die Ausnahme an den auftretenden wurde Typ ausgepackt und verglichen. Dieser Vergleich können einen systemeigenen normal aufgefangen werden C++-Typ.
Wenn catch eine Klausel des Typs SEHException oder eine ihrer Basisklassen zuerst untersucht wird, fängt die Klausel die Ausnahme ab. Daher sollten Sie alle catch-Klauseln platzieren, die systemeigenen C++-Typen zuerst abfangen, bevor alle catch-Klauseln von CLR.
Hinweis
catch(Object^)
und
catch(...)
fangen beide einen ausgelösten Typ einschließlich SEH Ausnahmen ab.
Wenn ein nicht verwalteter Typ von catch (Object^) abgefangen wird, zerstört nicht das ausgelöste Objekt.
Wenn wir nicht verwaltete Ausnahmen, empfohlen ausgelöst oder abgefangen werden, dass Sie die Compileroption /EHsc anstelle von /EHs oder /EHa verwenden.
Siehe auch
Referenz
safe_cast (Komponentenerweiterungen für C++)
Ausnahmebehandlung in Visual C++