Sdílet prostřednictvím


Základní pojmy v použití spravovaných výjimky

Toto téma popisuje zpracování výjimek v spravované aplikace.To znamená, že aplikace, která je kompilována s /clr možnost kompilátoru.

V tomto tématu

  • Vyvolání výjimky pod/CLR

  • Try/Catch bloky pro CLR rozšíření

Poznámky

Pokud kompilujete s /clr možnost, lze zpracovávat výjimky CLR, stejně jako standardní zpracování výjimek v C++ a zpracování strukturovaných výjimek (SEH).Výjimka CLR je jakákoli výjimka vyvolána spravované typu.System::Exception třída poskytuje mnoho užitečných metod pro zpracování výjimky CLR a doporučuje jako základní třída pro třídy, uživatelem definované výjimky.

Lov typy výjimek, které jsou odvozeny z rozhraní není podporován v rámci /clr.Navíc společný jazykový modul runtime neumožňuje zachytit výjimky přetečení zásobníku; proces bude ukončen na Výjimka přetečení zásobníku.

Další informace o rozdílech ve zpracování výjimek v spravovaných a nespravovaných aplikací naleznete v tématu rozdíly v výjimka zpracování chování v rámci spravovaného rozšíření jazyka C++.

Vyvolání výjimky pod/CLR

Výraz throw C++ rozšířen tak, aby vyvolat popisovač k typu CLR.Následující příklad vytvoří typ vlastní výjimky a potom vyvolá instanci tohoto 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 hodnoty musí být zabaleny před vyvolání:

// clr_exception_handling_2.cpp
// compile with: /clr /c
value struct MyValueStruct {
   int i;
};

void GlobalFunction() {
   MyValueStruct v = {11};
   throw (MyValueStruct ^)v;
}

Try/Catch bloky pro CLR rozšíření

Stejné akci/ve skutečné blok struktura může být použita pro lov CLR a nativní výjimky:

// 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 );
      }
   }
}

Výsledek

In 'catch(CMyClass& catchC)'
2
In 'catch(MyStruct^ catchException)'
11

Pořadí objektů C++ unwind

Unwind dochází u všech objektů jazyka C++ s destruktory, které mohou být v zásobníku běhu mezi aktivační funkce a funkce zpracování.Vzhledem k tomu, že typy CLR jsou přiděleny na haldě, unwind nevztahuje na ně.

Pořadí událostí pro výjimky je následující:

  1. Modul runtime prochází zásobník pro klauzuli catch vhodné nebo v případě SEH, výjimkou filtr SEH k zachycení výjimky.Catch klauzule jsou prohledána nejprve lexikální a dynamicky dolů zásobníku volání.

  2. Jakmile je nalezen správný obslužnou rutinu, zásobník je oddělen k tomuto bodu.Pro každé volání funkce v zásobníku jsou místní objekty destructed a __finally jsou spouštěny bloky od většiny vnořených ven.

  3. Jakmile zásobník je oddělen, se spustí klauzule catch.

Lov nespravované typy

Při vyvolání typ nespravované objektu je vnořen výjimka typu System::Runtime.InteropServices::SEHException.Při hledání vhodné skutečné klauzule, máte dvě možnosti.

  • V případě nativního typu C++ je výjimka nebalených a ve srovnání s byl zjištěn typ.Toto srovnání umožňuje nativního typu C++ k lovu obvyklým způsobem.

  • Však pokud ve skutečné klauzule typu SEHException nebo některý z jeho základních tříd je nejprve zkontrolován, klauzule bude zachytit výjimku.Proto byste měli umístit všechny klauzule catch které skutečné typy nativní C++ nejprve před žádné catch klauzule typy CLR.

Všimněte si, že

catch(Object^)

a

catch(...)

zachytí i libovolný vyvolané včetně výjimek SEH.

Pokud nespravovaný typ je zachycena catch(Object^), nezničí vyvolané objektu.

Při vyvolání nebo lov nespravované výjimky, doporučujeme použít /EHsc možnost kompilátoru namísto /EHs nebo /EHa.

Viz také

Referenční dokumentace

safe_cast (rozšíření komponent C++)

Zpracování výjimek v jazyce Visual C++

Další zdroje

Zpracování výjimek (rozšíření komponent C++)