Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Obsługa wyjątków strukturalnych (SEH) to rozszerzenie firmy Microsoft do języków C i C++ do obsługi niektórych wyjątkowych sytuacji kodu, takich jak błędy sprzętowe, bezpiecznie. Mimo że systemy Windows i Microsoft C++ obsługują standard SEH, zalecamy używanie standardowej obsługi wyjątków C++ w standardzie ISO w kodzie C++. Dzięki temu kod jest bardziej przenośny i elastyczny. Jednak aby zachować istniejący kod lub określonego rodzaju programów, nadal może być konieczne użycie SEH.
Specyficzne dla firmy Microsoft:
Gramatyka
try-except-statement
:
__try
compound-statement
__except
(
filter-expression
)
compound-statement
try-finally-statement
:
__try
compound-statement
__finally
compound-statement
Uwagi
Za pomocą protokołu SEH można upewnić się, że zasoby, takie jak bloki pamięci i pliki, są prawidłowo zwalniane, jeśli wykonanie nieoczekiwanie zakończy się. Można również obsłużyć konkretne problemy — na przykład za mało pamięci — za pomocą zwięzłego kodu ustrukturyzowanego, który nie opiera się na goto
instrukcjach ani skomplikowanych testach kodów powrotnych.
Instrukcje try-except
i try-finally
, o których mowa w tym artykule, to rozszerzenia firmy Microsoft dla języków C i C++. Obsługują SEH, umożliwiając aplikacjom kontrolę nad programem po zdarzeniach, które w przeciwnym razie zakończą wykonywanie. Mimo że SEH współpracuje z plikami źródłowymi języka C++, nie jest specjalnie zaprojektowany dla języka C++. Jeśli używasz SEH w programie C++, który kompilujesz przy użyciu /EHa
opcji lub /EHsc
, destruktory dla obiektów lokalnych są wywoływane, ale inne zachowanie wykonywania może nie być oczekiwane. Aby zapoznać się z ilustracją, zobacz przykład w dalszej części tego artykułu. W większości przypadków zamiast SEH zalecamy użycie obsługi wyjątków standardu ISO C++. Korzystając z obsługi wyjątków w języku C++, możesz upewnić się, że kod jest bardziej przenośny i można obsługiwać wyjątki dowolnego typu.
Jeśli masz kod C, który używa protokołu SEH, możesz go mieszać z kodem C++, który korzysta z obsługi wyjątków języka C++. Aby uzyskać informacje, zobacz Obsługa wyjątków strukturalnych w języku C++.
Istnieją dwa mechanizmy SEH:
Procedury obsługi wyjątków lub
__except
bloki, które mogą odpowiadać na lub odrzucać wyjątek nafilter-expression
podstawie wartości. Aby uzyskać więcej informacji, zobacztry-except
instrukcję.Procedury obsługi zakończenia lub
__finally
bloki, które są zawsze wywoływane, niezależnie od tego, czy wyjątek powoduje zakończenie, czy nie. Aby uzyskać więcej informacji, zobacztry-finally
instrukcję.
Te dwa rodzaje procedur obsługi są odrębne, ale są ściśle powiązane przez proces znany jako odwijanie stosu. W przypadku wystąpienia wyjątku strukturalnego system Windows wyszukuje ostatnio zainstalowaną procedurę obsługi wyjątków, która jest obecnie aktywna. Procedura obsługi może wykonać jedną z trzech czynności:
Nie można rozpoznać wyjątku i przekazać kontrolę do innych procedur obsługi (
EXCEPTION_CONTINUE_SEARCH
).Rozpoznaj wyjątek, ale go odrzuć (
EXCEPTION_CONTINUE_EXECUTION
).Rozpoznaj wyjątek i obsłuż go (
EXCEPTION_EXECUTE_HANDLER
).
Procedura obsługi wyjątków, która rozpoznaje wyjątek, może nie znajdować się w funkcji, która była uruchomiona po wystąpieniu wyjątku. Może to być w funkcji znacznie wyższej na stosie. Obecnie uruchomiona funkcja i wszystkie inne funkcje w ramce stosu są przerywane. W trakcie tego procesu stos jest unwound. Oznacza to, że lokalne zmienne niestatyczne zakończonych funkcji są czyszczone ze stosu.
W miarę odwijania stosu system operacyjny wywołuje wszystkie programy obsługi zakończenia napisane dla każdej funkcji. Korzystając z procedury obsługi zakończenia, należy wyczyścić zasoby, które w przeciwnym razie pozostaną otwarte z powodu nietypowego zakończenia. Jeśli wprowadzono sekcję krytyczną, możesz zamknąć ją w procedurze obsługi kończenia. Gdy program zostanie zamknięty, możesz wykonać inne zadania sprzątania, takie jak zamykanie i usuwanie plików tymczasowych.
Następne kroki
Przykład
Jak wspomniano wcześniej, destruktory dla obiektów lokalnych są wywoływane, jeśli używasz SEH w programie języka C++ i skompiluj je przy użyciu /EHa
opcji lub /EHsc
. Jednak zachowanie podczas wykonywania może nie być oczekiwane, jeśli używasz również wyjątków języka C++. W tym przykładzie pokazano te różnice behawioralne.
#include <stdio.h>
#include <Windows.h>
#include <exception>
class TestClass
{
public:
~TestClass()
{
printf("Destroying TestClass!\n");
}
};
__declspec(noinline) void TestCPPEX()
{
#ifdef CPPEX
printf("Throwing C++ exception\n");
throw std::exception("");
#else
printf("Triggering SEH exception\n");
volatile int *pInt = 0x00000000;
*pInt = 20;
#endif
}
__declspec(noinline) void TestExceptions()
{
TestClass d;
TestCPPEX();
}
int main()
{
__try
{
TestExceptions();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
printf("Executing SEH __except block\n");
}
return 0;
}
Jeśli używasz /EHsc
polecenia do skompilowania tego kodu, ale lokalne makro CPPEX
kontroli testów jest niezdefiniowane, TestClass
destruktor nie zostanie uruchomiony. Dane wyjściowe wyglądają następująco:
Triggering SEH exception
Executing SEH __except block
Jeśli używasz /EHsc
polecenia do kompilowania kodu i CPPEX
jest definiowany za pomocą polecenia /DCPPEX
(tak, aby zgłaszany był wyjątek języka C++), TestClass
destruktor jest uruchamiany, a dane wyjściowe wyglądają następująco:
Throwing C++ exception
Destroying TestClass!
Executing SEH __except block
Jeśli używasz /EHa
polecenia do skompilowania kodu, destruktor wykonuje, TestClass
czy wyjątek został zgłoszony przy użyciu standardowego wyrażenia C++ throw
, czy też przy użyciu SEH. Oznacza to, czy CPPEX
jest definiowany, czy nie. Dane wyjściowe wyglądają następująco:
Throwing C++ exception
Destroying TestClass!
Executing SEH __except block
Aby uzyskać więcej informacji, zobacz /EH
(Model obsługi wyjątków).
KONIEC specyficzny dla firmy Microsoft
Zobacz też
Obsługa wyjątków
Słowa kluczowe
<exception>
Błędy i obsługa wyjątków
Obsługa wyjątków strukturalnych (Windows)