_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