_set_se_translator
Nastavte funkci zpětného volání pro jednotlivá vlákna, která přeloží výjimky Win32 (strukturované výjimky jazyka C) na výjimky typu C++.
Syntaxe
_se_translator_function _set_se_translator(
_se_translator_function seTransFunction
);
Parametry
seTransFunction
Ukazatel na funkci translatoru strukturované výjimky jazyka C, kterou napíšete.
Vrácená hodnota
Vrátí ukazatel na předchozí funkci translatoru zaregistrovanou _set_se_translator
pomocí funkce , aby předchozí funkce byla později obnovena. Pokud nebyla nastavena žádná předchozí funkce, lze návratová hodnota použít k obnovení výchozího chování; tato hodnota může být nullptr
.
Poznámky
Funkce _set_se_translator
poskytuje způsob, jak zpracovat výjimky Win32 (strukturované výjimky jazyka C) jako výjimky typu C++. Chcete-li, aby každá výjimka jazyka C byla zpracována obslužnou rutinou jazyka C++ catch
, nejprve definujte obálku výjimky jazyka C, která se dá použít nebo odvozena z atributu konkrétního typu třídy k výjimce jazyka C. Chcete-li použít tuto třídu, nainstalujte vlastní funkci překladače výjimek jazyka C, která je volána interním mechanismem zpracování výjimek při každém vyvolání výjimky jazyka C. V rámci funkce translator můžete vyvolat libovolnou typovou výjimku, kterou lze zachytit odpovídající obslužnou rutinou jazyka C++ catch
.
Při použití _set_se_translator
je nutné použít /EHa
možnost .
Pokud chcete zadat vlastní funkci překladu, zavolejte _set_se_translator
jako argument název funkce překladu. Funkce translatoru, kterou píšete, se volá jednou pro každé vyvolání funkce v zásobníku, který obsahuje try
bloky. Neexistuje žádná výchozí funkce překladače.
Funkce translator by neměla provádět více než vyvolání výjimky typu C++. Pokud kromě vyvolání (například zápisu do souboru protokolu) se váš program nemusí chovat podle očekávání, protože počet vyvolání funkce translatoru závisí na platformě.
V prostředí s více vlákny se funkce translatoru spravují samostatně pro každé vlákno. Každé nové vlákno musí nainstalovat vlastní funkci translatoru. Každé vlákno je tedy zpoplatněno vlastním zpracováním překladu. _set_se_translator
je specifická pro jednu knihovnu DLL s více vlákny, může nainstalovat jinou funkci překladu.
Funkce seTransFunction
, kterou píšete, musí být nativní kompilovaná funkce (nekompilována s /clr
). Jako argumenty musí být celé číslo bez znaménka a ukazatel na strukturu Win32 _EXCEPTION_POINTERS
. Argumenty jsou návratové hodnoty volání rozhraní API GetExceptionCode
a GetExceptionInformation
funkcí Win32.
typedef void (__cdecl *_se_translator_function)(unsigned int, struct _EXCEPTION_POINTERS* );
Pro _set_se_translator
, existují důsledky při dynamickém propojení s CRT; jiná knihovna DLL v procesu může volat _set_se_translator
a nahradit vaši obslužnou rutinu vlastním.
Při použití _set_se_translator
ze spravovaného kódu (kód zkompilovaný /clr
pomocí) nebo smíšeného nativního a spravovaného kódu má překladač vliv pouze na výjimky generované v nativním kódu. Všechny spravované výjimky vygenerované ve spravovaném kódu (například při vyvolání System::Exception
) se nesměrují přes funkci translatoru. Výjimky vyvolané ve spravovaném kódu pomocí funkce RaiseException
Win32 nebo způsobené systémovou výjimkou, jako je dělení nulou výjimka, se směrují přes překladač.
Požadavky
Rutina | Požadovaný hlavičkový soubor |
---|---|
_set_se_translator |
<eh.h> |
Další informace o kompatibilitě najdete v tématu Kompatibilita.
Příklad: Chyba zachycení __try
výjimky
Tato ukázka zabalí volání pro nastavení strukturovaného překladače výjimek a obnovení starého RAII
ve třídě . Scoped_SE_Translator
Tato třída umožňuje zavést překladač specifický pro obor jako jednu deklaraci. Destruktor třídy obnoví původní překladač, když ovládací prvek opustí obor.
// crt_settrans.cpp
// compile with: cl /W4 /EHa crt_settrans.cpp
#include <stdio.h>
#include <windows.h>
#include <eh.h>
#include <exception>
class SE_Exception : public std::exception
{
private:
const unsigned int nSE;
public:
SE_Exception() noexcept : SE_Exception{ 0 } {}
SE_Exception( unsigned int n ) noexcept : nSE{ n } {}
unsigned int getSeNumber() const noexcept { return nSE; }
};
class Scoped_SE_Translator
{
private:
const _se_translator_function old_SE_translator;
public:
Scoped_SE_Translator( _se_translator_function new_SE_translator ) noexcept
: old_SE_translator{ _set_se_translator( new_SE_translator ) } {}
~Scoped_SE_Translator() noexcept { _set_se_translator( old_SE_translator ); }
};
void SEFunc()
{
__try
{
printf( "In __try, about to force exception\n" );
int x = 5;
int y = 0;
int *p = &y;
*p = x / *p;
}
__finally
{
printf( "In __finally\n" );
}
}
void trans_func( unsigned int u, EXCEPTION_POINTERS* )
{
throw SE_Exception( u );
}
int main()
{
Scoped_SE_Translator scoped_se_translator{ trans_func };
try
{
SEFunc();
}
catch( const SE_Exception& e )
{
printf( "Caught a __try exception, error %8.8x.\n", e.getSeNumber() );
}
}
In __try, about to force exception
In __finally
Caught a __try exception, error c0000094.
Příklad: Chyba zachycení SE_Exception
Přestože funkce poskytované _set_se_translator
ve spravovaném kódu nejsou k dispozici, je možné použít toto mapování v nativním kódu, i když je tento nativní kód v kompilaci pod /clr
přepínačem, pokud je nativní kód označen pomocí #pragma unmanaged
. Pokud je ve spravovaném kódu vyvolána strukturovaná výjimka, která se má mapovat, musí být označen #pragma unmanaged
kód, který vygeneruje a zpracovává výjimku. Následující kód ukazuje možné použití. Další informace naleznete v tématu Direktivy pragma a __pragma
klíčová slova._Pragma
// crt_set_se_translator_clr.cpp
// compile with: cl /W4 /clr crt_set_se_translator_clr.cpp
#include <windows.h>
#include <eh.h>
#include <stdio.h>
#include <exception>
int thrower_func( int i ) {
int y = 0;
int *p = &y;
*p = i / *p;
return 0;
}
class SE_Exception : public std::exception
{
private:
const unsigned int nSE;
public:
SE_Exception() noexcept : SE_Exception{ 0 } {}
SE_Exception( unsigned int n ) noexcept : nSE{ n } {}
unsigned int getSeNumber() const noexcept { return nSE; }
};
class Scoped_SE_Translator
{
private:
const _se_translator_function old_SE_translator;
public:
Scoped_SE_Translator( _se_translator_function new_SE_translator ) noexcept
: old_SE_translator{ _set_se_translator( new_SE_translator ) } {}
~Scoped_SE_Translator() noexcept { _set_se_translator( old_SE_translator ); }
};
#pragma unmanaged
void my_trans_func( unsigned int u, PEXCEPTION_POINTERS )
{
throw SE_Exception( u );
}
void DoTest()
{
try
{
thrower_func( 10 );
}
catch( const SE_Exception& e )
{
printf( "Caught SE_Exception, error %8.8x\n", e.getSeNumber() );
}
catch(...)
{
printf( "Caught unexpected SEH exception.\n" );
}
}
#pragma managed
int main() {
Scoped_SE_Translator scoped_se_translator{ my_trans_func };
DoTest();
}
Caught SE_Exception, error c0000094
Viz také
Rutiny zpracování výjimek
set_terminate
set_unexpected
terminate
unexpected