Podstawowe pojęcia związane z używaniem wyjątków zarządzanych
W tym temacie omówiono obsługi wyjątków w zarządzanych aplikacji.Czyli aplikacji, która została skompilowana z /clr opcję kompilatora.
W tym temacie
Rzucanie wyjątki w obszarze/CLR
Try i Catch bloki dla rozszerzeń CLR
Uwagi
Jeśli kompilacji z /clr opcji, może obsługiwać wyjątki CLR, jak również standardowe obsługi wyjątków C++ i obsługi structured exception (SEH).Wyjątek CLR jest każdy wyjątek typu zarządzanego.System::Exception klasa oferuje wiele przydatnych metod przetwarzania CLR wyjątków i jest zalecany jako klasa podstawowa dla klas wyjątków zdefiniowanej przez użytkownika.
Przechwytywanie wyjątku typy pochodzące z interfejsu nie jest obsługiwana w obszarze /clr.Ponadto common language runtime nie pozwala przechwytywać wyjątków przepełnienia stosu; Wyjątek przepełnienia stosu zakończy proces.
Aby uzyskać więcej informacji na temat różnic w Obsługa wyjątków w aplikacjach zarządzany i niezarządzany, zobacz różnice w wyjątku obsługi zachowanie pod zarządzane rozszerzenia języka C++.
Rzucanie wyjątki w obszarze/CLR
Wyrażenie rzucać C++ jest rozszerzany rzucić dojścia do typu CLR.Poniższy przykład tworzy typ wyjątku niestandardowych i następnie generuje instancję tego typu:
// 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;
}
Typ wartości należy pakować przed wypadnięcia:
// clr_exception_handling_2.cpp
// compile with: /clr /c
value struct MyValueStruct {
int i;
};
void GlobalFunction() {
MyValueStruct v = {11};
throw (MyValueStruct ^)v;
}
Try i Catch bloki dla rozszerzeń CLR
Taki sam Spróbuj/połowu struktury bloku może służyć do połowu zarówno CLR oraz wyjątki macierzystym:
// 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 );
}
}
}
Dane wyjściowe
In 'catch(CMyClass& catchC)'
2
In 'catch(MyStruct^ catchException)'
11
Kolejność odwracanie obiektów języka C++
Odwracanie występuje dla obiektów C++ z destruktorów, które mogą być na stosie wykonywania między rzucanie funkcje i obsługi.Ponieważ typy CLR są przydzielane na stercie, odwracanie nie dotyczą ich.
Kolejność zdarzeń dla Wyrzucony wyjątek jest następująca:
Środowisko wykonawcze przeprowadza stosu szukam klauzuli catch właściwe, lub w przypadku zastępowania strukturalnej obsługi, z wyjątkiem filtr dla strukturalnej obsługi wyjątków do wyłapania wyjątku.CATCH klauzule przeszukiwane są po raz pierwszy w kolejności leksykalne, a następnie dynamicznie w dół stosu wywołań.
Gdy zostanie znaleziony poprawny program obsługi, stos jest zwiniętej do tego punktu.Dla każdego wywołania funkcji na stosie jej obiektów lokalnych są zniszczone i __finally są wykonywane bloki, od najbardziej zagnieżdżone na zewnątrz.
Po umieszczeniu zwiniętej stosu jest wykonywany klauzuli catch.
Połowu typy niezarządzanych
Gdy jest generowany, typ obiektu niezarządzanego, jest opatrywana wyjątek typu System::Runtime.InteropServices::SEHException.Podczas wyszukiwania do właściwego połowu klauzuli, istnieją dwie możliwości.
Jeśli okaże się typem macierzystym C++, wyjątek następnie rozpakować i w porównaniu z typem napotkał.Porównanie to pozwala typem macierzystym C++ zostać schwytane w normalny sposób.
Jednakże jeśli połowu klauzuli typu SEHException lub którykolwiek z jej klas podstawowych najpierw zbadać, klauzula przechwytuje wyjątek.W związku z tym należy umieścić wszystkie klauzule połowów, które złapać macierzystym C++ rodzaj najpierw przed żadnego połowu klauzule typy CLR.
Należy zauważyć, że
catch(Object^)
i
catch(...)
będzie zarówno efektywnej dowolnego typu wyrzucony w tym zastępowania strukturalnej obsługi wyjątków.
Jeśli typ niezarządzany jest objęte catch(Object^), nie zniszczy wyrzucony obiektu.
Podczas rzucania lub połowu niezarządzanych wyjątki, zaleca się użycie /EHsc opcję kompilatora zamiast /EHs lub /EHa.
Zobacz też
Informacje
Obsługa wyjątków w języku Visual C++