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.
Penting
Info dalam topik ini berlaku untuk semua versi Windows 10, dan yang lebih baru. Kita akan menyebut versi tersebut di sini sebagai "Windows", memanggil pengecualian apa pun jika perlu.
Set API mengandalkan dukungan OS di pemuat pustaka untuk memperkenalkan pengalihan namespace modul ke dalam proses pengikatan pustaka. Nama kontrak set API tidak memberi nama file. Loader melakukan pengalihan run-time dari nama kontrak tersebut ke biner host yang berisi implementasi.
Ketika loader menemukan dependensi pada SET API pada run time, loader berkonsultasi dengan data konfigurasi dalam gambar untuk mengidentifikasi biner host untuk set API tersebut. Data konfigurasi ini disebut skema set API . Skema ini dirakit sebagai properti OS, dan pemetaan antara set API dan biner dapat berbeda tergantung pada biner mana yang disertakan pada perangkat tertentu. Skema inilah yang memungkinkan fungsi yang diimpor dalam satu biner dirutekan dengan benar pada perangkat yang berbeda, bahkan ketika modul yang menghosting implementasi telah diganti namanya, dibagi terpisah, atau direfaktor.
Bagaimana impor mencapai implementasi
Biner dapat mencapai implementasi set API dengan dua cara, yang diputuskan berdasarkan nama dalam tabel impornya:
- Impor set API langsung. Biner mengimpor nama kontrak set API. Loader menyelesaikan nama tersebut melalui skema set API ke biner host pada perangkat saat ini.
- Impor modul warisan. Biner mengimpor nama modul Windows warisan, seperti samplefeature.dll. Pada edisi yang mengirimkan modul tersebut, loader mengikatnya secara langsung. Pada edisi yang telah menggantikannya, penerus terbalik yang membawa nama yang sama mengalihkan impor ke set API, yang kemudian diselesaikan pemuat melalui skema.
Nama mana yang berakhiran dalam tabel impor Anda biasanya ditentukan oleh pustaka yang Anda tautkan daripada oleh sumber yang Anda tulis. Lihat pustaka payung Windows.
Lebih suka nama kontrak set API untuk kode yang menargetkan versi Windows saat ini. Loader menyelesaikannya langsung ke host, tanpa penerus di antaranya. Impor nama modul warisan saat Anda memerlukan satu biner yang juga berjalan pada versi Windows yang dirilis sebelum set API ada. Penerusan terbalik membuat biner yang bekerja pada edisi tempat modul warisan telah diganti.
Impor set API langsung
Resolusi adalah urutan tiga langkah:
- Biner Anda mengimpor nama kontrak set API, atau meneruskan satu ke LoadLibrary.
- Loader melihat kontrak dalam skema set API pada perangkat saat ini, dan menemukan biner host tempat skema memetakannya.
- Loader memuat biner host dan mengikat fungsi yang diimpor ke ekspor host.
Karena pemetaan berada dalam skema daripada dalam sistem file, impor yang sama dapat diselesaikan ke biner yang berbeda di perangkat yang berbeda:
| Device |
api-win-core-samplefeature peta ke |
|---|---|
| Perangkat yang menyertakan fitur | samplefeature.dll |
| Perangkat yang mengirimkan implementasi yang direfaktor | samplefeaturecore.dll |
| Perangkat yang tidak menyertakan fitur | Tidak dipetakan |
Nama-nama samplefeature yang digunakan di sini adalah nama ilustrasi untuk komponen Windows fiktif.
Biner yang mengkonsumsi tidak menyadari host mana yang terikat padanya. Itulah titik mekanisme: kontrak stabil, sementara modul yang mengimplementasikannya bebas untuk berubah dari satu perangkat ke perangkat berikutnya.
Impor nama kontrak diselesaikan dalam satu operasi, tanpa melibatkan modul penerus perantara. Ini adalah bentuk yang paling efisien, dan jalur normal untuk kode yang ditulis terhadap set API.
Nama set API dan akhiran .dll
Karena pemetaan disimpan dalam skema daripada pada disk, nama set API yang diakhir dengan .dll tidak merujuk ke file nama tersebut. Bagian .dll hanyalah konvensi penamaan, yang dibawa dari cara nama modul dieja dalam tabel impor. Nama set API lebih seperti alias, atau nama virtual, untuk file DLL fisik.
Ketika operasi loader menerima nama yang dimulai dengan api- atau ext-, loader merutekannya ke runtime set API, ekstensi loader yang menyelesaikan kontrak melalui skema. Runtime set API mengurai nama menurut aturan penamaan set API daripada sebagai nama file, sehingga akhiran .dll bukan bagian dari nama kontrak yang diselesaikan. Sertakan akhiran saat Anda bekerja dari nama seperti yang muncul dalam tabel impor; jika tidak, Anda dapat membiarkannya.
Loader menyelesaikan kedua bentuk nama kontrak, nama kontrak versi dan alias kontrak, melalui skema yang sama. Untuk konvensi yang mengatur nama-nama ini, lihat NAMA kontrak set API.
Stabilitas nama tidak sama dengan ketersediaan
Nama set API stabil di seluruh perangkat Windows, dalam arti nama yang sama selalu mengidentifikasi kontrak yang sama di mana pun diakui. Itu adalah properti namespace layanan, bukan jaminan tentang perangkat tertentu.
Kontrak tertentu dapat tidak ada dari perangkat, atau ada tetapi tidak dipetakan ke host. Tidak ada tentang nama yang memberitahu Anda yang mana. Untuk mengetahui apakah implementasinya benar-benar ada, lihat Mendeteksi ketersediaan set API.
Resolusi apa yang diperlukan
Untuk panggilan melalui set API untuk mencapai implementasi, semua hal berikut harus ditangguhkan:
- Kontrak ada dalam skema pada perangkat saat ini.
- Skema memetakan kontrak ke biner host, dan host tersebut dapat dimuat.
- Host mengekspor fungsi spesifik yang dipanggil biner Anda.
Ketika salah satu dari itu tidak tahan, di mana kegagalan muncul tergantung pada cara Anda mengimpor set API:
| Gaya impor | Perilaku ketika kontrak tidak dapat diselesaikan |
|---|---|
| Impor statis | Proses gagal dimulai. Loader menyelesaikan impor statis sebelum salah satu kode Anda berjalan. |
| Impor yang dimuat keterlambatan | Proses dimulai secara normal. Resolusi ditangguhkan ke panggilan pertama ke API, di mana kode Anda dapat menangani kegagalan. |
Ekspor yang hilang dilaporkan secara terpisah dari kontrak yang hilang; biner yang mengimpor fungsi yang tidak diekspor host gagal dengan kesalahan titik masuk yang hilang.
Apa beban yang berhasil tidak memberi tahu Anda
Resolusi mengikat kontrak ke host. Ini tidak mengevaluasi status kemampuan individu dalam kontrak tersebut.
Kontrak dapat mengatur kemampuannya yang tersedia secara individual ke dalam grup bernama. Grup dapat tidak tersedia pada perangkat meskipun kontrak yang membawanya diselesaikan secara normal, karena loader mengikat granularitas kontrak dan tidak berkonsultasi dengan status grup saat mengikat. Itu disengaja: menolak untuk mengikat host berakibat fatal terhadap impor statis, sehingga loader mengambil jalur permisif dan meninggalkan pertanyaan yang lebih halus kepada pemanggil.
Konsekuensi untuk kode Anda adalah bahwa beban yang berhasil, atau panggilan LoadLibrary yang berhasil, bukan bukti bahwa kemampuan tertentu tersedia. Ajukan pertanyaan tersebut secara eksplisit dengan kueri ketersediaan. Lihat Mendeteksi ketersediaan set API.
Set API opsional dan pemuatan penundaan
Jika aplikasi Anda memanggil set API yang mungkin tidak ada, pemeriksaan ketersediaan sendiri tidak cukup: dengan impor statis, proses gagal dimulai, sehingga eksekusi tidak pernah mencapai pemeriksaan.
Agar jalur kode opsional tetap dapat dijangkau, konfigurasikan modul yang membawa API opsional untuk pemuatan penundaan, atau atasi target secara dinamis dengan LoadLibrary dan GetProcAddress setelah kueri ketersediaan berhasil. Untuk detail kedua pendekatan, lihat Mendeteksi ketersediaan set API.
Penerusan terbalik
Meskipun nama set API menyediakan namespace layanan yang stabil untuk modul di seluruh perangkat, tidak selalu praktis untuk mengonversi setiap biner ke sistem ini. Aplikasi mungkin telah digunakan secara umum selama bertahun-tahun, dan kompilasi ulang binernya mungkin tidak layak. Beberapa aplikasi juga perlu terus berjalan pada sistem yang dibangun sebelum set API tertentu diperkenalkan.
Untuk mengakomodasi itu, edisi yang tidak membawa modul asli mencakup sekumpulan penerus terbalik: biner kompatibilitas yang membawa nama modul yang awalnya diperkenalkan pada PC Windows, dan yang mengalihkan ekspor mereka ke set API.
Edisi desktop lengkap mengirimkan modul asli, sehingga impor nama modul warisan mengikat ke modul seperti yang selalu ada. Pada edisi yang telah menggantikan modul tersebut, penerus terbalik yang membawa nama yang sama mencakup kesenjangan.
Operasi pemuat berperilaku seperti ini:
- Loader disajikan dengan dependensi pada nama modul PC Windows warisan yang tidak ada di perangkat.
- Loader menemukan penerus terbalik yang membawa nama modul tersebut, dan memuatnya.
- Penerus terbalik mengalihkan fungsi yang diimpor ke set API.
- Loader menyelesaikan bahwa API diatur melalui skema, seperti yang dijelaskan sebelumnya dalam topik ini.
Secara konseptual, pemetaan terlihat seperti ini:
DLL yang diimpor: samplefeature.dll
- Pada edisi yang memiliki modul asli: samplefeature.dll
- Pada edisi yang telah menggantinya: samplefeature.dll penerus terbalik - ->
api-win-core-samplefeature>samplefeaturecore.dll
Batas jalur ini adalah cakupan ekspor. Penerus terbalik hanya membawa ekspor yang memiliki set API yang setara, sehingga tidak selalu mengekspor setiap fungsi yang dilakukan modul asli. Biner yang mengimpor fungsi yang tidak dibawa penerus terbalik gagal dimuat dengan kesalahan titik masuk yang hilang.
Penerusan terbalik juga merupakan alasan untuk tidak memperlakukan resolusi yang berhasil sebagai bukti bahwa implementasi hadir. Panggilan GetProcAddress terhadap nama modul warisan dapat mengembalikan penunjuk fungsi valid yang diselesaikan ke stub yang mengembalikan kesalahan. Ketersediaan kueri secara eksplisit sebagai gantinya. Lihat Mendeteksi ketersediaan set API.
Nota
Penerusan terbalik hanya mencakup subset permukaan API Win32. Ini tidak memungkinkan aplikasi yang menargetkan versi desktop Windows berjalan di semua perangkat Windows. Jika biner Anda menargetkan versi Windows saat ini, nama kontrak set API adalah pilihan yang lebih langsung.