_set_se_translator

Win32 例外 (C 構造化例外) を C++ の型指定された例外に変換するスレッドごとのコールバック関数を設定します。Set a per-thread callback function to translate Win32 exceptions (C structured exceptions) into C++ typed exceptions.

構文Syntax

_se_translator_function _set_se_translator(
    _se_translator_function seTransFunction
);

パラメーターParameters

seTransFunction
ユーザーが作成した C 構造化例外の変換関数へのポインター。Pointer to a C structured exception translator function that you write.

戻り値Return Value

は、 _set_se_translator 前の関数を後で復元できるように、によって登録された前の変換関数へのポインターを返します。Returns a pointer to the previous translator function registered by _set_se_translator, so that the previous function can be restored later. 前の関数が設定されていない場合は、戻り値を使用して既定の動作を復元できます。この値にはを指定でき nullptr ます。If no previous function has been set, the return value can be used to restore the default behavior; this value can be nullptr.

注釈Remarks

関数は、 _set_se_translator Win32 例外 (c 構造化例外) を C++ 型の例外として処理する方法を提供します。The _set_se_translator function provides a way to handle Win32 exceptions (C structured exceptions) as C++ typed exceptions. 各 C 例外が C++ ハンドラーによって処理されるようにするに catch は、まず、特定のクラス型を c 例外に属性化するために使用または派生できる 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. このクラスを使用するには、C 例外が発生するたびに内部例外処理メカニズムによって呼び出されるカスタム 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. 変換関数内では、一致する C++ ハンドラーによってキャッチされる、型指定された例外をスローでき catch ます。Within your translator function, you can throw any typed exception that can be caught by a matching C++ catch handler.

_Set_se_translator を使用する場合は、を使用する必要があり /EHa ます。 You must use /EHa when using _set_se_translator.

カスタム変換関数を指定するには、 _set_se_translator 変換関数の名前を引数として使用してを呼び出します。To specify a custom translation function, call _set_se_translator using the name of your translation function as its argument. 記述する変換関数は、ブロックを持つスタック上の関数呼び出しごとに1回呼び出され try ます。The translator function that you write is called once for each function invocation on the stack that has try blocks. 既定の変換関数はありません。There's no default translator function.

変換関数は、C++ 型の例外をスローする以外のことは何もすべきではありません。Your translator function should do no more than throw a C++ typed exception. (たとえば、ログファイルへの書き込みなどで) スローに加えて何かを実行すると、変換関数が呼び出される回数がプラットフォームに依存しているため、プログラムが予期したとおりに動作しない可能性があります。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.

マルチスレッド環境では、変換関数は各スレッドとは別に管理されます。In a multithreaded environment, translator functions are maintained separately for each thread. 新しい各スレッドは、それぞれの変換関数をインストールする必要があります。Each new thread needs to install its own translator function. したがって、各スレッドが、それぞれの変換処理を担当します。Thus, each thread is in charge of its own translation handling. _set_se_translator は、1つのスレッドに固有のもので、別の DLL で別の変換関数をインストールできます。_set_se_translator is specific to one thread--another DLL can install a different translation function.

記述する Setransfunction 関数は、ネイティブコンパイル関数 (/clr でコンパイルされません) である必要があります。The seTransFunction function that you write must be a native-compiled function (not compiled with /clr). 引数として、符号なし整数と Win32 構造体へのポインターを受け取る必要があり _EXCEPTION_POINTERS ます。It must take an unsigned integer and a pointer to a Win32 _EXCEPTION_POINTERS structure as arguments. 引数は、それぞれ Win32 API および関数への呼び出しの戻り値 GetExceptionCode GetExceptionInformation です。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* );

_Set_se_translator の場合、CRT に動的にリンクするときには影響があります。プロセス内の別の DLL が _set_se_translator を呼び出し、ハンドラーをそれ自体のに置き換える場合があります。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.

マネージコード (/clr でコンパイルされたコード) または混合ネイティブコードまたはマネージコードから _set_se_translator を使用する場合は、変換プログラムがネイティブコードでのみ生成される例外に影響することに注意してください。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. マネージコードで生成されたマネージ例外 (発生する場合など System::Exception ) は、変換関数によってルーティングされません。Any managed exceptions generated in managed code (such as when raising System::Exception) aren't routed through the translator function. Win32 関数 RaiseException を使用してマネージコードで発生した例外や、ゼロ除算例外などのシステム例外によって発生した例外は、変換プログラムを通じてルーティングされます。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.

必要条件Requirements

ルーチンによって返される値Routine 必須ヘッダーRequired header
_set_se_translator_set_se_translator <eh.h>

互換性について詳しくは、「 Compatibility」をご覧ください。For more compatibility information, see Compatibility.

例: キャッチ __try 例外エラーExample: Catch __try exception error

このサンプルでは、の呼び出しをラップして、構造化例外変換器を設定し、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. このクラスを使用すると、スコープ固有の変換を1つの宣言として導入できます。This class lets you introduce a scope-specific translator as a single declaration. クラスデストラクターは、コントロールがスコープから外れたときに元のトランスレーターを復元します。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.

例: キャッチ SE_Exception エラーExample: Catch SE_Exception error

_Set_se_translator によって提供される機能はマネージコードでは使用できませんが、ネイティブコードが /clr スイッチの下のコンパイルに含まれていても、ネイティブコードがを使用して示されている限り、ネイティブコードでこのマッピングを使用でき #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. 構造化例外が、マップされるマネージコードでスローされている場合は、例外を生成して処理するコードをとしてマークする必要があり #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. 次のコードは考えられる使用法を示しています。The following code shows a possible use. 詳細については、「プラグマ ディレクティブと __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

参照See also

例外処理ルーチンException Handling Routines
set_terminate
set_unexpected
terminate
unexpected\