Freigeben über


_set_se_translator

Legen Sie eine Rückruffunktion pro Thread fest, um Win32-Ausnahmen (strukturierte C-Ausnahmen) in C++-typierte Ausnahmen zu übersetzen.

Syntax

_se_translator_function _set_se_translator(
    _se_translator_function seTransFunction
);

Parameter

seTransFunction
Zeiger auf eine strukturierte C-Ausnahmeübersetzerfunktion, die Sie schreiben.

Rückgabewert

Gibt einen Zeiger auf die vorherige Übersetzerfunktion zurück, die von _set_se_translator registriert wurde, sodass die vorherige Funktion später wiederhergestellt werden kann. Wenn keine vorherige Funktion festgelegt wurde, kann der Rückgabewert verwendet werden, um das Standardverhalten wiederherzustellen. Dieser Wert kann nullptr sein.

Hinweise

Die Funktion _set_se_translator bietet eine Möglichkeit zur Behandlung von Win32-Ausnahmen (strukturierte C-Ausnahmen) als C++-typisierte Ausnahmen. Damit jede C-Ausnahme von einem C++-catch-Handler behandelt wird, definieren Sie zunächst eine Wrapperklasse für eine C-Ausnahme definieren, die verwendet oder abgeleitet werden kann, um einer C-Ausnahme einen speziellen Klassentyp zuzuordnen. Um diese Klasse zu verwenden, installieren Sie eine benutzerdefinierte C-Ausnahmeübersetzungsfunktion, die bei jedem Auslösen einer C-Ausnahme vom internen Mechanismus für die Ausnahmebehandlung aufgerufen wird. In der Übersetzerfunktion können Sie beliebige typisierte Ausnahmen auslösen, die von einem übereinstimmenden C++-catch-Handler abgefangen werden kann.

Sie müssen die /EHa Option verwenden, wenn Sie sie verwenden _set_se_translator.

Rufen Sie _set_se_translator zum Angeben einer benutzerdefinierten Übersetzungsfunktion den Namen der Übersetzungsfunktion als Argument auf. Die Übersetzerfunktion, die Sie schreiben, wird einmal für jeden Funktionsaufruf im Stapel mit try-Blöcken aufgerufen. Es gibt keine Standardübersetzerfunktion.

Ihre Übersetzerfunktion sollte lediglich eine C++-typisierte Ausnahme auslösen. Wenn sie zusätzlich zum Auslösen (z. B. Schreiben in eine Protokolldatei) nicht wie erwartet funktioniert, verhält sich Ihr Programm möglicherweise nicht wie erwartet, da die Anzahl der Aufrufe der Übersetzerfunktion plattformabhängig ist.

In einer Multithreadumgebung werden die Übersetzerfunktionen für jeden Thread separat verwaltet. Jeder neue Thread muss eine eigene Übersetzerfunktion installieren. Daher ist jeder Thread für die eigene Übersetzungsbehandlung verantwortlich. _set_se_translator ist spezifisch für einen Thread- eine andere DLL kann eine andere Übersetzungsfunktion installieren.

Die seTransFunction von Ihnen geschriebene Funktion muss eine systemeigene kompilierte Funktion sein (nicht kompiliert mit /clr). Als Argumente sind eine ganze Zahl ohne Vorzeichen und ein Zeiger auf eine Win32-_EXCEPTION_POINTERS-Struktur erforderlich. Die Argumente sind die Rückgabewerte von Aufrufen der GetExceptionCode- und GetExceptionInformation-Funktion der Win32-API.

typedef void (__cdecl *_se_translator_function)(unsigned int, struct _EXCEPTION_POINTERS* );

Für _set_se_translator sind Auswirkungen bei der dynamischen Verknüpfung mit der CRT gegeben; eine andere DLL im Prozess ruft möglicherweise _set_se_translator auf und ersetzt Ihren Handler durch einen eigenen.

Wenn Sie aus verwaltetem Code (kompilierter /clrCode) oder gemischtem systemeigenem und verwaltetem Code verwenden_set_se_translator, wirkt sich der Übersetzer nur auf Ausnahmen aus, die nur im systemeigenen Code generiert werden. Alle verwalteten Ausnahmen, die in verwaltetem Code generiert werden (z. B. beim Auslösen System::Exception), werden nicht über die Übersetzerfunktion weitergeleitet. Mithilfe der Win32-Funktion RaiseException oder durch eine Systemausnahme wie eine Division durch Null-Ausnahme in verwaltetem Code ausgelöste Ausnahmen werden nicht über den Übersetzer weitergeleitet.

Anforderungen

Routine Erforderlicher Header
_set_se_translator <eh.h>

Weitere Informationen zur Kompatibilität finden Sie unter Kompatibilität.

Beispiel: Ausnahmefehler abfangen __try

In diesem Beispiel werden die Aufrufe zum Festlegen eines strukturierten Ausnahmeübersetzers und zum Wiederherstellen des alten in einer RAII Klasse Scoped_SE_Translatorumgebrochen. Mit dieser Klasse können Sie einen bereichsspezifischen Übersetzer als einzelne Deklaration einführen. Der Klassen destruktor stellt den ursprünglichen Übersetzer wieder her, wenn das Steuerelement den Bereich verlässt.

// 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.

Beispiel: Catch SE_Exception error

Obwohl die von _set_se_translator ihnen bereitgestellte Funktionalität nicht im verwalteten Code verfügbar ist, ist es möglich, diese Zuordnung in systemeigenem Code zu verwenden, auch wenn sich dieser systemeigene Code in einer Kompilierung unter der /clr Option befindet, solange der systemeigene Code mit der Verwendung #pragma unmanagedangegeben wird. Wenn eine strukturierte Ausnahme in verwaltetem Code ausgelöst wird, der zugeordnet werden soll, muss der Code, der die Ausnahme generiert und behandelt, markiert #pragma unmanagedwerden. Der folgende Code veranschaulicht eine mögliche Verwendung. Weitere Informationen finden Sie unter Pragma-Direktiven und den __pragma Schlüsselwörtern_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

Siehe auch

Ausnahmebehandlungsroutinen
set_terminate
set_unexpected
terminate
unexpected