Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Concetti di base in utilizzando le eccezioni gestite vengono illustrate la gestione delle eccezioni nelle applicazioni gestite.In questo argomento, le differenze dal comportamento standard di gestione delle eccezioni e alcune restrizioni sono descritte in dettaglio.Per ulteriori informazioni, vedere La funzione di _set_se_translator.
Saltando infine di un blocco
Nel codice nativo C/C++, uscire da un blocco difinally di utilizzando gestione delle eccezioni strutturata (SEH) è consentito sebbene scriva un avviso.In /clr, uscire da un blocco di finally causa un errore:
// clr_exception_handling_4.cpp
// compile with: /clr
int main() {
try {}
finally {
return 0; // also fails with goto, break, continue
}
} // C3276
Generare eccezioni all'interno di un filtro eccezioni
Quando viene generata un'eccezione durante l'elaborazione di filtro eccezioni nel codice gestito, l'eccezione viene rilevata e trattata come se restituisce 0 del filtro.
Ciò si differenzia dal comportamento nel codice nativo in cui l'eccezione annidata viene generata un'eccezione, il campo di ExceptionRecord nella struttura di EXCEPTION_RECORD (restituiti da GetExceptionInformation) viene impostata e set che il campo di ExceptionFlags il 0x10 dispone di un bit.Nell'esempio seguente viene illustrata la differenza nel comportamento:
// clr_exception_handling_5.cpp
#include <windows.h>
#include <stdio.h>
#include <assert.h>
#ifndef false
#define false 0
#endif
int *p;
int filter(PEXCEPTION_POINTERS ExceptionPointers) {
PEXCEPTION_RECORD ExceptionRecord =
ExceptionPointers->ExceptionRecord;
if ((ExceptionRecord->ExceptionFlags & 0x10) == 0) {
// not a nested exception, throw one
*p = 0; // throw another AV
}
else {
printf("Caught a nested exception\n");
return 1;
}
assert(false);
return 0;
}
void f(void) {
__try {
*p = 0; // throw an AV
}
__except(filter(GetExceptionInformation())) {
printf_s("We should execute this handler if "
"compiled to native\n");
}
}
int main() {
__try {
f();
}
__except(1) {
printf_s("The handler in main caught the "
"exception\n");
}
}
Output
Caught a nested exception
We should execute this handler if compiled to native
Rigenerate annullata l'associazione
/clr non supporta rigenerare eccezioni fuori di un gestore catch (noto come generare annullata l'associazione).Le eccezioni di questo tipo sono considerate come generare C++ standard.Se un generare annullata l'associazione viene visualizzato quando si verifica un'eccezione gestita attiva, l'eccezione viene eseguito il wrapping come eccezione e quindi esiste C++.Le eccezioni di questo tipo possono essere rilevate solo come eccezione di tipo System::SEHException.
Nell'esempio seguente viene illustrato un nuovo gestito di eccezione come eccezione C++:
// clr_exception_handling_6.cpp
// compile with: /clr
using namespace System;
#include <assert.h>
#include <stdio.h>
void rethrow( void ) {
// This rethrow is a dissasociated rethrow.
// The exception would be masked as SEHException.
throw;
}
int main() {
try {
try {
throw gcnew ApplicationException;
}
catch ( ApplicationException^ ) {
rethrow();
// If the call to rethrow() is replaced with
// a throw statement within the catch handler,
// the rethrow would be a managed rethrow and
// the exception type would remain
// System::ApplicationException
}
}
catch ( ApplicationException^ ) {
assert( false );
// This will not be executed since the exception
// will be masked as SEHException.
}
catch ( Runtime::InteropServices::SEHException^ ) {
printf_s("caught an SEH Exception\n" );
}
}
Output
caught an SEH Exception
Filtri eccezioni e EXCEPTION_CONTINUE_EXECUTION
Se un filtro restituisce EXCEPTION_CONTINUE_EXECUTION in un'applicazione gestita, viene considerato come se il filtro abbia restituito EXCEPTION_CONTINUE_SEARCH.Per ulteriori informazioni su queste costanti, vedere try-except l'istruzione.
Nell'esempio seguente viene illustrata questa differenza:
// clr_exception_handling_7.cpp
#include <windows.h>
#include <stdio.h>
#include <assert.h>
int main() {
int Counter = 0;
__try {
__try {
Counter -= 1;
RaiseException (0xe0000000|'seh',
0, 0, 0);
Counter -= 2;
}
__except (Counter) {
// Counter is negative,
// indicating "CONTINUE EXECUTE"
Counter -= 1;
}
}
__except(1) {
Counter -= 100;
}
printf_s("Counter=%d\n", Counter);
}
Output
Counter=-3
La funzione di _set_se_translator
La funzione di conversione, set da una chiamata a _set_se_translator, intercetti di interessa solo nel codice non gestito.Nell'esempio seguente viene illustrata questa limitazione:
// clr_exception_handling_8.cpp
// compile with: /clr /EHa
#include <iostream>
#include <windows.h>
#include <eh.h>
#pragma warning (disable: 4101)
using namespace std;
using namespace System;
#define MYEXCEPTION_CODE 0xe0000101
class CMyException {
public:
unsigned int m_ErrorCode;
EXCEPTION_POINTERS * m_pExp;
CMyException() : m_ErrorCode( 0 ), m_pExp( NULL ) {}
CMyException( unsigned int i, EXCEPTION_POINTERS * pExp )
: m_ErrorCode( i ), m_pExp( pExp ) {}
CMyException( CMyException& c ) : m_ErrorCode( c.m_ErrorCode ),
m_pExp( c.m_pExp ) {}
friend ostream& operator <<
( ostream& out, const CMyException& inst ) {
return out << "CMyException[\n" <<
"Error Code: " << inst.m_ErrorCode << "]";
}
};
#pragma unmanaged
void my_trans_func( unsigned int u, PEXCEPTION_POINTERS pExp ) {
cout << "In my_trans_func.\n";
throw CMyException( u, pExp );
}
#pragma managed
void managed_func() {
try {
RaiseException( MYEXCEPTION_CODE, 0, 0, 0 );
}
catch ( CMyException x ) {}
catch ( ... ) {
printf_s("This is invoked since "
"_set_se_translator is not "
"supported when /clr is used\n" );
}
}
#pragma unmanaged
void unmanaged_func() {
try {
RaiseException( MYEXCEPTION_CODE,
0, 0, 0 );
}
catch ( CMyException x ) {
printf("Caught an SEH exception with "
"exception code: %x\n", x.m_ErrorCode );
}
catch ( ... ) {}
}
// #pragma managed
int main( int argc, char ** argv ) {
_set_se_translator( my_trans_func );
// It does not matter whether the translator function
// is registered in managed or unmanaged code
managed_func();
unmanaged_func();
}
Output
This is invoked since _set_se_translator is not supported when /clr is used
In my_trans_func.
Caught an SEH exception with exception code: e0000101
Vedere anche
Riferimenti
safe_cast (Estensioni del componente C++)
Gestione delle eccezioni in Visual C++