Bagikan melalui


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 HINSTANCEFARPROC). 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 HINSTANCEFARPROC), 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.

  • , HMODULEjika 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

Dukungan linker untuk DLL yang dimuat keterlambatan