Penanganan dan pemberitahuan kesalahan
Jika program Anda menggunakan DLL yang dimuat tunda, program harus menangani kesalahan dengan kuat, karena kegagalan yang terjadi saat program berjalan akan mengakibatkan pengecualian yang tidak tertangani. Penanganan kegagalan terdiri dari dua bagian: Pemulihan melalui kait, dan pelaporan melalui pengecualian.
Untuk informasi selengkapnya tentang penanganan dan pemberitahuan kesalahan penundaan DLL, lihat Memahami fungsi pembantu.
Untuk informasi selengkapnya tentang fungsi kait, lihat Struktur dan definisi konstan.
Pemulihan melalui hook
Kode Anda mungkin perlu pulih pada kegagalan, atau untuk menyediakan pustaka atau rutinitas alternatif. Anda dapat memberikan kait ke fungsi pembantu yang dapat menyediakan kode alternatif, atau memperbaiki situasi. Rutinitas kait perlu mengembalikan nilai yang sesuai, sehingga pemrosesan dapat dilanjutkan (atau HINSTANCE
FARPROC
). Atau, dapat mengembalikan 0 untuk menunjukkan bahwa pengecualian harus dilemparkan. Ini juga bisa melemparkan pengecualiannya sendiri atau longjmp
keluar dari kait. Ada kait pemberitahuan dan kait kegagalan. Rutinitas yang sama dapat digunakan untuk keduanya.
Hook pemberitahuan
Hook pemberitahuan beban penundaan dipanggil tepat sebelum tindakan berikut diambil dalam rutinitas pembantu:
Handel tersimpan ke pustaka diperiksa untuk melihat apakah handel tersebut telah dimuat.
LoadLibrary
dipanggil untuk mencoba beban DLL.GetProcAddress
dipanggil untuk mencoba mendapatkan alamat prosedur.Kembali ke thunk beban impor penundaan.
Hook pemberitahuan diaktifkan:
Dengan memberikan definisi baru penunjuk
__pfnDliNotifyHook2
yang diinisialisasi untuk menunjuk ke fungsi Anda sendiri yang menerima pemberitahuan.-atau-
Dengan mengatur penunjuk
__pfnDliNotifyHook2
ke fungsi hook Anda sebelum panggilan apa pun ke DLL bahwa program menunda pemuatan.
Jika pemberitahuan adalah dliStartProcessing
, fungsi hook dapat mengembalikan:
NULL
Pembantu default menangani pemuatan DLL. Ini berguna untuk memanggil hanya untuk tujuan informasi.
penunjuk fungsi
Melewati penanganan penundaan-muatan default. Ini memungkinkan Anda menyediakan handler beban Anda sendiri.
Jika pemberitahuan adalah dliNotePreLoadLibrary
, fungsi hook dapat mengembalikan:
0, jika hanya ingin pemberitahuan informasi.
HMODULE
untuk DLL yang dimuat, jika memuat DLL itu sendiri.
Jika pemberitahuan adalah dliNotePreGetProcAddress
, fungsi hook dapat mengembalikan:
0, jika hanya ingin pemberitahuan informasi.
Alamat fungsi yang diimpor, jika fungsi kait mendapatkan alamat itu sendiri.
Jika pemberitahuan adalah dliNoteEndProcessing
, nilai pengembalian fungsi hook diabaikan.
Jika penunjuk ini diinisialisasi (bukan nol), pembantu beban penundaan memanggil fungsi pada titik pemberitahuan tertentu sepanjang eksekusinya. Penunjuk fungsi memiliki definisi berikut:
// The "notify hook" gets called for every call to the
// delay load helper. This allows a user to hook every call and
// skip the delay load helper entirely.
//
// dliNotify == {
// dliStartProcessing |
// dliNotePreLoadLibrary |
// dliNotePreGetProc |
// dliNoteEndProcessing}
// on this call.
//
ExternC
PfnDliHook __pfnDliNotifyHook2;
// This is the failure hook, dliNotify = {dliFailLoadLib|dliFailGetProc}
ExternC
PfnDliHook __pfnDliFailureHook2;
Pemberitahuan meneruskan DelayLoadInfo
struktur ke fungsi kait bersama dengan nilai pemberitahuan. Data ini identik dengan data yang digunakan oleh rutinitas pembantu beban penundaan. Nilai pemberitahuan akan menjadi salah satu nilai yang ditentukan dalam Struktur dan definisi konstanta.
Kait kegagalan
Kait kegagalan diaktifkan dengan cara yang sama dengan kait pemberitahuan. Rutinitas kait perlu mengembalikan nilai yang sesuai sehingga pemrosesan dapat dilanjutkan (atau HINSTANCE
FARPROC
), atau 0 untuk menunjukkan bahwa pengecualian harus dilemparkan.
Variabel penunjuk yang mengacu pada fungsi yang ditentukan pengguna adalah:
// This is the failure hook, dliNotify = {dliFailLoadLib|dliFailGetProc}
ExternC
PfnDliHook __pfnDliFailureHook2;
Struktur DelayLoadInfo
berisi semua data terkait yang diperlukan untuk pelaporan terperinci tentang kesalahan, termasuk nilai dari GetLastError
.
Jika pemberitahuan adalah dliFailLoadLib
, fungsi hook dapat mengembalikan:
0, jika tidak dapat menangani kegagalan.
,
HMODULE
jika kegagalan menghubungkan memperbaiki masalah dan memuat pustaka itu sendiri.
Jika pemberitahuan adalah dliFailGetProc
, fungsi hook dapat mengembalikan:
0, jika tidak dapat menangani kegagalan.
Alamat proc yang valid (alamat fungsi impor), jika kegagalan kait berhasil mendapatkan alamat itu sendiri.
Laporkan dengan menggunakan pengecualian
Jika semua yang diperlukan untuk menangani kesalahan adalah membatalkan prosedur, tidak ada kait yang diperlukan, selama kode pengguna dapat menangani pengecualian.
Tunda kode pengecualian beban
Kode pengecualian terstruktur dapat dinaikkan ketika kegagalan terjadi selama beban tertunda. Nilai pengecualian ditentukan dengan menggunakan VcppException
makro:
//
// Exception information
//
#define FACILITY_VISUALCPP ((LONG)0x6d)
#define VcppException(sev,err) ((sev) | (FACILITY_VISUALCPP<<16) | err)
LoadLibrary
Untuk kegagalan, standar VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND)
dilemparkan. GetProcAddress
Untuk kegagalan, kesalahan yang dilemparkan adalah VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND)
. Pengecualian meneruskan penunjuk ke DelayLoadInfo
struktur. Ini ada dalam nilai yang LPDWORD
diambil oleh GetExceptionInformation
dari EXCEPTION_RECORD
struktur, di ExceptionInformation[0]
bidang .
Jika bit yang salah diatur di grAttrs
bidang , pengecualian ERROR_INVALID_PARAMETER
akan dilemparkan. Pengecualian ini, untuk semua niat dan tujuan, fatal.
Untuk informasi selengkapnya, lihat Struktur dan definisi konstanta.
Baca juga
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk