Compartir a través de


_set_se_translator

Establezca una función de devolución de llamada por subproceso para convertir las excepciones de Win32 (excepciones estructuradas de C) en excepciones con tipo de C++.

Sintaxis

_se_translator_function _set_se_translator(
    _se_translator_function seTransFunction
);

Parámetros

seTransFunction
Puntero a una función de traductor de excepciones estructuradas de C que se escriba.

Valor devuelto

Devuelve un puntero a la función de traductor anterior registrada por _set_se_translator para que después se pueda restaurar dicha función. Si no se ha establecido ninguna función anterior, se puede usar el valor devuelto para restaurar el comportamiento predeterminado; este valor puede ser nullptr.

Comentarios

La función _set_se_translator proporciona una manera para controlar las excepciones Win32 (excepciones estructuradas de C) como excepciones con tipo de C++. Para permitir que cada excepción de C se pueda controlar con un controlador catch de C++, primero debe definir una clase contenedora de excepciones de C que se pueda usar (o de la que se pueda derivar) con el objetivo de atribuir un tipo de clase específico a una excepción de C. Para usar esta clase, instale una función de traductor de excepciones de C a la que llama el mecanismo de control de excepciones internas cada vez que se produce una excepción de C. Dentro de la función de traductor puede producir cualquier excepción con tipo que se pueda detectar con un controlador catch de C++ que coincida.

Debe usar la /EHa opción cuando use _set_se_translator.

Para especificar una función de traducción personalizada, llame a _set_se_translator con el nombre de la función de traducción como argumento. La función de traductor que escriba se llama una vez para cada invocación de función en la pila que tenga bloques try. No hay ninguna función de traductor predeterminada.

La función de traductor solo debe generar una excepción con tipo de C++. Si hace algo además de iniciar (por ejemplo, escribir en un archivo de registro, por ejemplo), es posible que el programa no se comporte según lo esperado porque el número de invocaciones de la función translator depende de la plataforma.

En un entorno multiproceso, las funciones de traductor se mantienen por separado para cada subproceso. Cada subproceso nuevo debe instalar su propia función de traductor. Por lo tanto, cada subproceso se encarga de su propio control de traducción. _set_se_translator es específico de un subproceso; otro archivo DLL puede instalar una función de traducción diferente.

La función seTransFunction que escriba debe ser una función compilada de forma nativa (no compilada con /clr). Debe tomar un entero sin signo y un puntero a la estructura _EXCEPTION_POINTERS de Win32 como argumentos. Los argumentos son los valores devueltos de las llamadas a las funciones GetExceptionCode y GetExceptionInformation de la API Win32, respectivamente.

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

Para _set_se_translator, hay implicaciones a la hora de vincularse dinámicamente a CRT; otro archivo DLL del proceso podría llamar a _set_se_translator y reemplazar el controlador por el suyo propio.

Cuando se usa _set_se_translator desde código administrado (código compilado con /clr) o código nativo y administrado mixto, el traductor afecta solo a las excepciones generadas en código nativo. Ninguna excepción administrada que se haya generado en el código administrado (por ejemplo, cuando se genera System::Exception) se enruta mediante la función de traductor. Las excepciones generadas en el código administrado mediante la función RaiseException de Win32 o producidas por una excepción del sistema (como una excepción de división por cero) se enrutan a través del traductor.

Requisitos

Routine Encabezado necesario
_set_se_translator <eh.h>

Para obtener más información sobre compatibilidad, consulte Compatibilidad.

Ejemplo: Detección del error de excepción __try

En este ejemplo se encapsulan las llamadas para establecer un traductor de excepciones estructurado y para restaurar el antiguo de una clase RAII, Scoped_SE_Translator. Esta clase permite introducir un traductor específico del ámbito como una única declaración. El destructor de clase restaura el traductor original cuando el control sale del ámbito.

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

Ejemplo: Detección del error SE_Exception

Aunque la funcionalidad proporcionada por _set_se_translator no está disponible en el código administrado, se puede usar esta asignación en el código nativo, incluso si dicho código está en una compilación en el modificador /clr, siempre y cuando el código nativo se indique mediante #pragma unmanaged. Si se genera una excepción estructurada en código administrado que se debe asignar, el código que genera y controla la excepción se debe marcar con #pragma unmanaged. En el siguiente código se muestra un uso posible. Para más información, consulte Directivas pragma y las palabras clave __pragma y _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

Consulte también

Rutinas de control de excepciones
set_terminate
set_unexpected
terminate
unexpected