Sdílet prostřednictvím


_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_translatorpomocí 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_translatorje 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ý /clrpomocí) 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 unmanagedkó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