Bagikan melalui


_set_se_translator

Atur fungsi panggilan balik per utas untuk menerjemahkan pengecualian Win32 (pengecualian terstruktur C) ke dalam pengecualian C++ yang diketik.

Sintaks

_se_translator_function _set_se_translator(
    _se_translator_function seTransFunction
);

Parameter

seTransFunction
Penunjuk ke fungsi penerjemah pengecualian terstruktur C yang Anda tulis.

Nilai hasil

Mengembalikan penunjuk ke fungsi penerjemah sebelumnya yang didaftarkan oleh _set_se_translator, sehingga fungsi sebelumnya dapat dipulihkan nanti. Jika tidak ada fungsi sebelumnya yang ditetapkan, nilai pengembalian dapat digunakan untuk memulihkan perilaku default; nilai ini bisa berupa nullptr.

Keterangan

Fungsi ini _set_se_translator menyediakan cara untuk menangani pengecualian Win32 (pengecualian terstruktur C) sebagai pengecualian C++ yang diketik. Untuk memungkinkan setiap pengecualian C ditangani oleh handler C++ catch , pertama-tama tentukan kelas pembungkus pengecualian C yang dapat digunakan, atau berasal dari, untuk mengaitkan jenis kelas tertentu ke pengecualian C. Untuk menggunakan kelas ini, instal fungsi penerjemah pengecualian C kustom yang dipanggil oleh mekanisme penanganan pengecualian internal setiap kali pengecualian C dinaikkan. Dalam fungsi penerjemah, Anda dapat melemparkan pengecualian jenis apa pun yang dapat ditangkap oleh handler C++ catch yang cocok.

Anda harus menggunakan /EHa opsi saat menggunakan _set_se_translator.

Untuk menentukan fungsi terjemahan kustom, panggil _set_se_translator menggunakan nama fungsi terjemahan Anda sebagai argumennya. Fungsi penerjemah yang Anda tulis dipanggil sekali untuk setiap pemanggilan fungsi pada tumpukan yang memiliki try blok. Tidak ada fungsi penerjemah default.

Fungsi penerjemah Anda harus melakukan tidak lebih dari melempar pengecualian C++ yang diketik. Jika melakukan sesuatu selain melempar (seperti menulis ke file log, misalnya) program Anda mungkin tidak bertingkah seperti yang diharapkan karena jumlah pemanggilan fungsi penerjemah bergantung pada platform.

Dalam lingkungan multithreaded, fungsi penerjemah dipertahankan secara terpisah untuk setiap utas. Setiap utas baru perlu menginstal fungsi penerjemahnya sendiri. Dengan demikian, setiap utas bertanggung jawab atas penanganan terjemahannya sendiri. _set_se_translator khusus untuk satu utas--DLL lain dapat menginstal fungsi terjemahan yang berbeda.

Fungsi seTransFunction yang Anda tulis harus berupa fungsi yang dikompilasi asli (tidak dikompilasi dengan /clr). Ini harus mengambil bilangan bulat yang tidak ditandatangani dan penunjuk ke struktur Win32 _EXCEPTION_POINTERS sebagai argumen. Argumen adalah nilai pengembalian panggilan ke API GetExceptionCode win32 dan GetExceptionInformation fungsi, masing-masing.

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

Untuk _set_se_translator, ada implikasi ketika secara dinamis menautkan ke CRT; DLL lain dalam proses mungkin memanggil _set_se_translator dan mengganti handler Anda dengan sendirinya.

Saat Anda menggunakan _set_se_translator dari kode terkelola (kode yang dikompilasi dengan /clr) atau kode asli dan terkelola campuran, penerjemah hanya memengaruhi pengecualian yang dihasilkan dalam kode asli. Setiap pengecualian terkelola yang dihasilkan dalam kode terkelola (seperti saat menaikkan System::Exception) tidak dirutekan melalui fungsi penerjemah. Pengecualian yang dimunculkan dalam kode terkelola menggunakan fungsi RaiseException Win32 atau disebabkan oleh pengecualian sistem seperti pembagian dengan pengecualian nol dirutekan melalui penerjemah.

Persyaratan

Rutin Header yang diperlukan
_set_se_translator <eh.h>

Untuk informasi kompatibilitas selengkapnya, lihat Kompatibilitas.

Contoh: Menangkap __try kesalahan pengecualian

Sampel ini membungkus panggilan untuk mengatur penerjemah pengecualian terstruktur dan memulihkan yang lama di RAII kelas , Scoped_SE_Translator. Kelas ini memungkinkan Anda memperkenalkan penerjemah khusus cakupan sebagai satu deklarasi. Destruktor kelas memulihkan penerjemah asli saat kontrol meninggalkan cakupan.

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

Contoh: Menangkap SE_Exception kesalahan

Meskipun fungsionalitas yang disediakan oleh _set_se_translator tidak tersedia dalam kode terkelola, dimungkinkan untuk menggunakan pemetaan ini dalam kode asli, bahkan jika kode asli tersebut berada dalam kompilasi di bawah /clr sakelar, selama kode asli ditunjukkan menggunakan #pragma unmanaged. Jika pengecualian terstruktur sedang dilemparkan dalam kode terkelola yang akan dipetakan, kode yang menghasilkan dan menangani pengecualian harus ditandai #pragma unmanaged. Kode berikut menunjukkan kemungkinan penggunaan. Untuk informasi selengkapnya, lihat Arahan Pragma dan __pragma kata kunci dan _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

Lihat juga

Rutinitas penanganan pengecualian
set_terminate
set_unexpected
terminate
unexpected