Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Topik ini membahas penanganan pengecualian dalam aplikasi terkelola. Artinya, aplikasi yang dikompilasi dengan opsi /clr compiler.
Dalam topik ini
Keterangan
Jika Anda mengkompilasi dengan opsi /clr , Anda dapat menangani pengecualian CLR serta kelas standar Exception menyediakan banyak metode yang berguna untuk memproses pengecualian CLR dan direkomendasikan sebagai kelas dasar untuk kelas pengecualian yang ditentukan pengguna.
Menangkap jenis pengecualian yang berasal dari antarmuka tidak didukung di bawah /clr. Selain itu, runtime bahasa umum tidak memperbolehkan penanganan pengecualian luapan tumpukan; pengecualian luapan tumpukan akan mengakhiri proses.
Untuk informasi selengkapnya tentang perbedaan penanganan pengecualian dalam aplikasi terkelola dan tidak terkelola, lihat Perbedaan perilaku penanganan pengecualian di bawah Ekstensi Terkelola untuk C++.
Melempar pengecualian di bawah /clr
Ekspresi throw C++ diperluas untuk melempar handle ke tipe CLR. Contoh berikut membuat jenis pengecualian kustom lalu melempar instans jenis tersebut:
// clr_exception_handling.cpp
// compile with: /clr /c
ref struct MyStruct: public System::Exception {
public:
int i;
};
void GlobalFunction() {
MyStruct^ pMyStruct = gcnew MyStruct;
throw pMyStruct;
}
Jenis nilai harus dikotak sebelum dilemparkan:
// clr_exception_handling_2.cpp
// compile with: /clr /c
value struct MyValueStruct {
int i;
};
void GlobalFunction() {
MyValueStruct v = {11};
throw (MyValueStruct ^)v;
}
Coba/Tangkap Blok untuk Ekstensi CLR
Struktur blok yang sama try/catch dapat digunakan untuk menangkap pengecualian CLR dan native:
// clr_exception_handling_3.cpp
// compile with: /clr
using namespace System;
ref struct MyStruct : public Exception {
public:
int i;
};
struct CMyClass {
public:
double d;
};
void GlobalFunction() {
MyStruct^ pMyStruct = gcnew MyStruct;
pMyStruct->i = 11;
throw pMyStruct;
}
void GlobalFunction2() {
CMyClass c = {2.0};
throw c;
}
int main() {
for ( int i = 1; i >= 0; --i ) {
try {
if ( i == 1 )
GlobalFunction2();
if ( i == 0 )
GlobalFunction();
}
catch ( CMyClass& catchC ) {
Console::WriteLine( "In 'catch(CMyClass& catchC)'" );
Console::WriteLine( catchC.d );
}
catch ( MyStruct^ catchException ) {
Console::WriteLine( "In 'catch(MyStruct^ catchException)'" );
Console::WriteLine( catchException->i );
}
}
}
Keluaran
In 'catch(CMyClass& catchC)'
2
In 'catch(MyStruct^ catchException)'
11
Urutan Unwinding untuk Objek C++
Unwinding terjadi untuk objek C++ apa pun dengan destruktor yang mungkin berada di tumpukan run-time antara fungsi pelemparan dan fungsi penanganan. Karena jenis CLR dialokasikan pada tumpukan, unwinding tidak berlaku untuk mereka.
Urutan peristiwa untuk pengecualian yang dilemparkan adalah sebagai berikut:
Runtime menelusuri tumpukan untuk mencari klausul tangkapan yang tepat, atau dalam kasus SEH, penyaring kecuali untuk SEH, agar bisa menangkap pengecualian. Klausa catch pertama-tama dicari dalam urutan leksikal, lalu secara dinamis ke bawah tumpukan panggilan.
Setelah handler yang benar ditemukan, tumpukan dilepaskan ke titik tersebut. Untuk setiap panggilan fungsi pada tumpukan, objek lokalnya dihancurkan dan blok __finally dijalankan, dari yang paling dalam ke luar.
Setelah tumpukan dilepas, klausul tangkapan dijalankan.
Menangkap Jenis Tidak Terkelola
Ketika objek tipe yang tidak dikelola dilemparkan, objek tersebut dibungkus dengan pengecualian jenis SEHException. Saat mencari klausul yang sesuai catch , ada dua kemungkinan.
Jika jenis C++ asli ditemui, pengecualian diuraikan dan dibandingkan dengan jenis yang ditemui. Perbandingan ini memungkinkan jenis C++ asli ditangani dengan cara yang biasa.
Namun, jika
catchklausul jenis SEHException atau salah satu kelas dasarnya diperiksa terlebih dahulu, klausul akan mencegat pengecualian. Oleh karena itu, Anda harus menempatkan semua klausa tangkapan yang menangkap tipe bawaan C++ terlebih dahulu sebelum ada klausa tangkapan tipe CLR.
Perhatikan bahwa
catch(Object^)
dan
catch(...)
keduanya akan menangkap jenis yang dilemparkan termasuk pengecualian SEH.
Jika tipe yang tidak terkelola ditangkap oleh catch(Object^), objek yang dilemparkan tidak akan dihancurkan.
Saat melempar atau menangkap pengecualian yang tidak dikelola, kami sarankan Anda menggunakan opsi kompilator /EHsc alih-alih /EH atau /EHa.