_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