_set_se_translator

Ustaw funkcję wywołania zwrotnego dla każdego wątku, aby przetłumaczyć wyjątki Win32 (wyjątki ustrukturyzowane w języku C) na wyjątki typizowane w języku C++.

Składnia

_se_translator_function _set_se_translator(
    _se_translator_function seTransFunction
);

Parametry

seTransFunction
Wskaźnik do funkcji translatora wyjątków ustrukturyzowanych języka C, którą piszesz.

Wartość zwracana

Zwraca wskaźnik do poprzedniej funkcji translatora zarejestrowanej przez _set_se_translatorelement , aby można było przywrócić poprzednią funkcję później. Jeśli nie ustawiono żadnej poprzedniej funkcji, wartość zwracana może służyć do przywrócenia domyślnego zachowania; może to być nullptrwartość .

Uwagi

Funkcja _set_se_translator umożliwia obsługę wyjątków Win32 (wyjątki ustrukturyzowane w języku C) jako wyjątki typizowane w języku C++. Aby zezwolić na obsługę każdego wyjątku języka C++ przez procedurę obsługi języka C++ catch , najpierw zdefiniuj klasę otoki wyjątków języka C, która może być używana lub pochodzi z klasy, aby przypisać określony typ klasy do wyjątku języka C. Aby użyć tej klasy, zainstaluj niestandardową funkcję translatora wyjątków języka C wywoływaną przez wewnętrzny mechanizm obsługi wyjątków za każdym razem, gdy zgłaszany jest wyjątek języka C. W funkcji translatora można zgłosić dowolny typowy wyjątek, który może zostać przechwycony przez pasującą procedurę obsługi języka C++ catch .

Należy użyć opcji w przypadku używania /EHa polecenia _set_se_translator.

Aby określić niestandardową funkcję tłumaczenia, wywołaj _set_se_translator metodę przy użyciu nazwy funkcji tłumaczenia jako argumentu. Funkcja translatora, którą piszesz, jest wywoływana raz dla każdego wywołania funkcji na stosie, który zawiera try bloki. Nie ma domyślnej funkcji translatora.

Funkcja translatora nie powinna wykonywać więcej niż zgłaszać wyjątek wpisany w języku C++. Jeśli oprócz zgłaszania (na przykład zapisywania w pliku dziennika) program może nie zachowywać się zgodnie z oczekiwaniami, ponieważ liczba wywołań funkcji translatora jest zależna od platformy.

W środowisku wielowątkowym funkcje translatora są obsługiwane oddzielnie dla każdego wątku. Każdy nowy wątek musi zainstalować własną funkcję translatora. W związku z tym każdy wątek jest odpowiedzialny za własną obsługę tłumaczenia. _set_se_translator jest specyficzny dla jednego wątku — inna biblioteka DLL może zainstalować inną funkcję tłumaczenia.

Zapisywana seTransFunction funkcja musi być funkcją skompilowana natywnie (nie skompilowana za pomocą /clrpolecenia ). Musi ona przyjmować niepodpisane liczby całkowite i wskaźnik do struktury Win32 _EXCEPTION_POINTERS jako argumentów. Argumenty są zwracanymi wartościami wywołań do interfejsu API GetExceptionCode Win32 i GetExceptionInformation funkcji, odpowiednio.

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

W przypadku _set_se_translatorprogramu występują implikacje podczas dynamicznego łączenia z CRT; inna biblioteka DLL w procesie może wywołać _set_se_translator i zastąpić procedurę obsługi własną.

W przypadku użycia z _set_se_translator kodu zarządzanego (kodu skompilowanego za pomocą /clrmetody ) lub mieszanego kodu natywnego i zarządzanego translator ma wpływ na wyjątki wygenerowane tylko w kodzie natywnym. Wszelkie wyjątki zarządzane wygenerowane w kodzie zarządzanym (na przykład podczas wywoływanie System::Exception) nie są kierowane przez funkcję translatora. Wyjątki zgłaszane w kodzie zarządzanym przy użyciu funkcji RaiseException Win32 lub spowodowane wyjątkiem systemu, takimi jak podział przez zero wyjątków, są kierowane przez tłumacza.

Wymagania

Procedura Wymagany nagłówek
_set_se_translator <eh.h>

Aby uzyskać więcej informacji o zgodności, zobacz Zgodność.

Przykład: Przechwyć __try błąd wyjątku

Ten przykład opakowuje wywołania w celu ustawienia translatora wyjątków strukturalnych i przywrócenia starego w RAII klasie Scoped_SE_Translator. Ta klasa umożliwia wprowadzenie translatora specyficznego dla zakresu jako pojedynczej deklaracji. Destruktor klas przywraca oryginalny translator, gdy kontrolka opuszcza zakres.

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

Chociaż funkcje udostępniane przez _set_se_translator program nie są dostępne w kodzie zarządzanym, można użyć tego mapowania w kodzie natywnym, nawet jeśli ten kod natywny znajduje się w kompilacji w /clr ramach przełącznika, o ile kod natywny jest wskazywany przy użyciu polecenia #pragma unmanaged. Jeśli wyjątek ustrukturyzowany jest zgłaszany w kodzie zarządzanym, który ma zostać zamapowany, kod, który generuje i obsługuje wyjątek, musi być oznaczony jako #pragma unmanaged. Poniższy kod pokazuje możliwe użycie. Aby uzyskać więcej informacji, zobacz Dyrektywy Pragma i __pragma słowa kluczowe i _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

Zobacz też

Procedury obsługi wyjątków
set_terminate
set_unexpected
terminate
unexpected