_set_se_translator

Ustaw funkcję wywołania zwrotnego dla wątku, aby przetłumaczyć wyjątki Win32 (wyjątki strukturalne C) na wyjątki z określonym językiem C++.Set a per-thread callback function to translate Win32 exceptions (C structured exceptions) into C++ typed exceptions.

SkładniaSyntax

_se_translator_function _set_se_translator(
    _se_translator_function seTransFunction
);

ParametryParameters

seTransFunction
Wskaźnik do zapisanej funkcji translatora wyjątków języka C.Pointer to a C structured exception translator function that you write.

Wartość zwracanaReturn Value

Zwraca wskaźnik do poprzedniej funkcji translatora zarejestrowanej przez _set_se_translator , aby można było przywrócić poprzednią funkcję.Returns a pointer to the previous translator function registered by _set_se_translator, so that the previous function can be restored later. Jeśli żadna Poprzednia funkcja nie została ustawiona, wartość zwracana może zostać użyta do przywrócenia zachowania domyślnego. Ta wartość może być równa nullptr .If no previous function has been set, the return value can be used to restore the default behavior; this value can be nullptr.

UwagiRemarks

_set_se_translator Funkcja zapewnia sposób obsługi wyjątków Win32 (wyjątki strukturalne C) jako wyjątki z definicją języka C++.The _set_se_translator function provides a way to handle Win32 exceptions (C structured exceptions) as C++ typed exceptions. Aby zezwolić na obsługę każdego wyjątku C przez catch procedurę obsługi języka C++, należy najpierw zdefiniować klasę otoki wyjątku C, która może być używana, lub pochodną od, aby poatrybucie określony typ klasy jako wyjątek C.To allow each C exception to be handled by a C++ catch handler, first define a C exception wrapper class that can be used, or derived from, to attribute a specific class type to a C exception. Aby użyć tej klasy, należy zainstalować niestandardową funkcję translatora wyjątków języka C, która jest wywoływana przez wewnętrzny mechanizm obsługi wyjątków za każdym razem, gdy zostanie zgłoszony wyjątek C.To use this class, install a custom C exception translator function that is called by the internal exception-handling mechanism each time a C exception is raised. W ramach funkcji translator można zgłosić każdy wpisany wyjątek, który może zostać przechwycony przez pasującą catch procedurę obsługi języka C++.Within your translator function, you can throw any typed exception that can be caught by a matching C++ catch handler.

Należy używać /EHa podczas korzystania z _set_se_translator.You must use /EHa when using _set_se_translator.

Aby określić niestandardową funkcję tłumaczenia, należy wywołać _set_se_translator użycie nazwy funkcji tłumaczenia jako argumentu.To specify a custom translation function, call _set_se_translator using the name of your translation function as its argument. Funkcja translatora, którą można napisać, jest wywoływana jednokrotnie dla każdego wywołania funkcji na stosie, który ma try bloki.The translator function that you write is called once for each function invocation on the stack that has try blocks. Brak domyślnej funkcji translatora.There's no default translator function.

Funkcja translatora nie powinna być dłuższa niż throw wyjątek z typem języka C++.Your translator function should do no more than throw a C++ typed exception. Jeśli to wszystko, oprócz zgłaszania (np. zapisu w pliku dziennika), program może nie zachowywać się zgodnie z oczekiwaniami, ponieważ liczba wywoływania funkcji translatora jest zależna od platformy.If it does anything in addition to throwing (such as writing to a log file, for example) your program might not behave as expected because the number of times the translator function is invoked is platform-dependent.

W środowisku wielowątkowym funkcje usługi Translator są obsługiwane osobno dla każdego wątku.In a multithreaded environment, translator functions are maintained separately for each thread. Każdy nowy wątek musi zainstalować własną funkcję translatora.Each new thread needs to install its own translator function. W ten sposób każdy wątek jest odpowiedzialny za obsługę translacji.Thus, each thread is in charge of its own translation handling. _set_se_translator jest specyficzny dla jednego wątku — inna Biblioteka DLL może instalować inną funkcję tłumaczenia._set_se_translator is specific to one thread--another DLL can install a different translation function.

Funkcja seTransFunction , którą pisze, musi być funkcją skompilowaną natywnie (nieskompilowana z/CLR).The seTransFunction function that you write must be a native-compiled function (not compiled with /clr). Musi przyjmować liczbę całkowitą bez znaku oraz wskaźnik do _EXCEPTION_POINTERS struktury Win32 jako argumenty.It must take an unsigned integer and a pointer to a Win32 _EXCEPTION_POINTERS structure as arguments. Argumenty są wartościami zwrotnymi wywołań odpowiednio do Win32 API GetExceptionCode i GetExceptionInformation funkcji.The arguments are the return values of calls to the Win32 API GetExceptionCode and GetExceptionInformation functions, respectively.

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

W przypadku _set_se_translator mają wpływ na dynamiczne łączenie z CRT; inna Biblioteka DLL w procesie może wywoływać _set_se_translator i zamienić swój program obsługi na własny.For _set_se_translator, there are implications when dynamically linking to the CRT; another DLL in the process might call _set_se_translator and replace your handler with its own.

W przypadku korzystania z _set_se_translator z kodu zarządzanego (kod skompilowany za pomocą/CLR) lub kodu natywnego i zarządzanego, należy pamiętać, że translator wpływa na wyjątki generowane tylko w kodzie natywnym.When using _set_se_translator from managed code (code compiled with /clr) or mixed native and managed code, be aware that the translator affects exceptions generated in native code only. Wszelkie zarządzane wyjątki generowane w kodzie zarządzanym (takie jak w przypadku podnoszenia System::Exception ) nie są kierowane przez funkcję translatora.Any managed exceptions generated in managed code (such as when raising System::Exception) aren't routed through the translator function. Wyjątki wywoływane w kodzie zarządzanym przy użyciu funkcji Win32Exception lub spowodowane przez wyjątek systemu, takie jak wyjątek dzielenia przez zero, są kierowane przez translatora.Exceptions raised in managed code using the Win32 function RaiseException or caused by a system exception like a divide by zero exception are routed through the translator.

WymaganiaRequirements

ProceduraRoutine Wymagany nagłówekRequired header
_set_se_translator_set_se_translator <eh.h>

Aby uzyskać więcej informacji o zgodności, zobacz zgodność.For more compatibility information, see Compatibility.

Przykład: błąd wyjątku przechwytywania __tryExample: Catch __try exception error

Ten przykład otacza wywołania w celu ustawienia translatora wyjątków strukturalnych i przywrócenia starego obiektu w klasie RAII Scoped_SE_Translator .This sample wraps the calls to set a structured exception translator and to restore the old one in an RAII class, Scoped_SE_Translator. Ta klasa umożliwia wprowadzenie translatora specyficznego dla zakresu jako pojedynczej deklaracji.This class lets you introduce a scope-specific translator as a single declaration. Destruktor klasy przywraca oryginalny translator, gdy kontrolka opuszcza zakres.The class destructor restores the original translator when control leaves the scope.

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

Przykład: błąd SE_Exception przechwytywaniaExample: Catch SE_Exception error

Chociaż funkcje zapewniane przez _set_se_translator nie są dostępne w kodzie zarządzanym, można użyć tego mapowania w kodzie natywnym, nawet jeśli ten kod natywny jest w kompilacji pod przełącznikiem /CLR , o ile kod natywny jest wskazywany przy użyciu #pragma unmanaged .Although the functionality provided by _set_se_translator isn't available in managed code, it's possible to use this mapping in native code, even if that native code is in a compilation under the /clr switch, as long as the native code is indicated using #pragma unmanaged. Jeśli wystąpi wyjątek strukturalny w kodzie zarządzanym, który ma zostać zamapowany, kod generujący i obsługujący wyjątek musi być oznaczony #pragma unmanaged .If a structured exception is being thrown in managed code that is to be mapped, the code that generates and handles the exception must be marked #pragma unmanaged. Poniższy kod pokazuje możliwe użycie.The following code shows a possible use. Aby uzyskać więcej informacji, zobacz dyrektywy pragma i słowo kluczowe __pragma.For more information, see Pragma Directives and the __Pragma Keyword.

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

Zobacz takżeSee also

Procedury obsługi wyjątkówException Handling Routines
set_terminate
set_unexpected
terminate
unexpected\