Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Basisconcepten voor het gebruik van beheerde uitzonderingen bespreken de verwerking van uitzonderingen in beheerde toepassingen. In dit onderwerp worden verschillen van het standaardgedrag van de afhandeling van uitzonderingen en enkele beperkingen uitgebreid besproken. Zie De functie _set_se_translator voor meer informatie.
Springen uit een laatste blok
In native C/C++-code is het toegestaan om uit een __finally blok te springen met behulp van structured exception handling (SEH), hoewel er een waarschuwing wordt gegenereerd. Bij gebruik van /clr veroorzaakt het springen uit een finally blok een fout:
// clr_exception_handling_4.cpp
// compile with: /clr
int main() {
try {}
finally {
return 0; // also fails with goto, break, continue
}
} // C3276
Uitzonderingen binnen een uitzonderingsfilter genereren
Wanneer er een uitzondering optreedt tijdens de verwerking van een uitzonderingsfilter in beheerde code, wordt de uitzondering gevangen en behandeld alsof het filter 0 retourneert.
Dit staat in contrast met het gedrag in systeemeigen code waarbij een geneste uitzondering wordt opgeroepen, het veld ExceptionRecord in de EXCEPTION_RECORD structuur (zoals geretourneerd door GetExceptionInformation) wordt ingesteld en het veld ExceptionFlags de 0x10 bit instelt. In het volgende voorbeeld ziet u dit verschil in gedrag:
// 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");
}
}
Uitvoer
Caught a nested exception
We should execute this handler if compiled to native
Ontkoppelde 'rethrows'
/clr biedt geen ondersteuning voor het opnieuw opwerpen van een uitzondering buiten een catch-handler (ook wel een ongelinkte heropworp genoemd). Uitzonderingen van dit type worden behandeld als een standaard C++-rethrow. Als er een ontkoppelde rethrow wordt aangetroffen wanneer er een actieve beheerde uitzondering is, wordt de uitzondering verpakt als een C++-uitzondering en vervolgens opnieuw geworpen. Uitzonderingen van dit type kunnen alleen worden opgevangen als uitzondering van het type SEHException.
In het volgende voorbeeld ziet u een beheerde uitzondering die opnieuw wordt gebruikt als een C++-uitzondering:
// 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" );
}
}
Uitvoer
caught an SEH Exception
Uitzonderingsfilters en EXCEPTION_CONTINUE_EXECUTION
Als een filter EXCEPTION_CONTINUE_EXECUTION retourneert in een beheerde toepassing, wordt het behandeld alsof het filter EXCEPTION_CONTINUE_SEARCH retourneert. Zie try-except Statement voor meer informatie over deze constanten.
In het volgende voorbeeld ziet u dit verschil:
// 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);
}
Uitvoer
Counter=-3
De functie _set_se_translator
De vertalerfunctie, ingesteld door een aanroep naar _set_se_translator, is alleen van invloed op vangsten in onbeheerde code. In het volgende voorbeeld ziet u deze beperking:
// 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();
}
Uitvoer
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
Zie ook
afhandeling van uitzonderingen
safe_cast
Afhandeling van uitzonderingen in MSVC