Menautkan ke file DLL dapat terjadi secara implisit pada waktu kompilasi tautan, atau secara eksplisit pada waktu proses. Either way, DLL akhirnya dimuat ke dalam ruang memori proses, dan semua titik masuk yang diekspor tersedia untuk aplikasi.
Jika digunakan secara eksplisit pada waktu proses, Anda menggunakan LoadLibrary()
dan GetProcAddress()
memuat DLL secara manual dan mendapatkan petunjuk ke fungsi yang perlu Anda panggil.
Jika ditautkan secara implisit saat program dibuat, maka stub untuk setiap ekspor DLL yang digunakan oleh program akan ditautkan ke program dari pustaka impor, dan stub tersebut diperbarui saat EXE dan DLL dimuat saat proses diluncurkan. (Ya, saya telah menyederhanakan lebih dari sedikit di sini ...)
Rintisan tersebut harus berasal dari suatu tempat, dan dalam rantai alat Microsoft mereka berasal dari bentuk khusus file .LIB yang disebut pustaka impor . .LIB yang diperlukan biasanya dibangun pada waktu yang sama dengan DLL, dan berisi rintisan untuk setiap fungsi yang diekspor dari DLL.
Yang membingungkan, versi statis dari pustaka yang sama juga akan dikirim sebagai file .LIB. Tidak ada cara sepele untuk membedakannya, kecuali bahwa LIB yang merupakan pustaka impor untuk DLL biasanya akan lebih kecil (seringkali jauh lebih kecil) daripada LIB statis yang cocok.
Jika Anda menggunakan toolchain GCC, secara kebetulan, Anda sebenarnya tidak memerlukan pustaka impor untuk mencocokkan DLL Anda. Versi linker Gnu yang di-porting ke Windows memahami DLL secara langsung, dan dapat mensintesis hampir semua stub yang diperlukan dengan cepat.
Memperbarui
Jika Anda tidak dapat menahan diri untuk tidak mengetahui di mana semua mur dan baut sebenarnya dan apa yang sebenarnya terjadi, selalu ada sesuatu di MSDN untuk membantu. Artikel Matt Pietrek, Pandangan Mendalam tentang Format File Eksekusi Portabel Win32 adalah gambaran umum yang sangat lengkap tentang format file EXE dan bagaimana itu dimuat dan dijalankan. Bahkan telah diperbarui untuk mencakup .NET dan lebih banyak lagi sejak pertama kali muncul di Majalah MSDN ca. 2002.
Selain itu, akan sangat membantu untuk mengetahui cara mempelajari dengan tepat DLL apa yang digunakan oleh suatu program. Alat untuk itu adalah Dependency Walker, alias depend.exe. Versi itu disertakan dengan Visual Studio, tetapi versi terbaru tersedia dari pembuatnya di http://www.dependencywalker.com/ . Ini dapat mengidentifikasi semua DLL yang ditentukan pada waktu tautan (baik pemuatan awal dan pemuatan tunda) dan juga dapat menjalankan program dan mengawasi setiap DLL tambahan yang dimuat pada waktu berjalan.
Perbarui 2
Saya telah mengubah beberapa teks sebelumnya untuk memperjelasnya saat membaca ulang, dan menggunakan istilah seni yang secara implisit dan eksplisit menghubungkan untuk konsistensi dengan MSDN.
Jadi, kami memiliki tiga cara agar fungsi perpustakaan dapat tersedia untuk digunakan oleh program. Pertanyaan selanjutnya yang jelas adalah: "Bagaimana saya memilih cara yang mana?"
Penautan statis adalah cara menghubungkan sebagian besar program itu sendiri. Semua file objek Anda terdaftar, dan dikumpulkan bersama ke file EXE oleh linker. Sepanjang jalan, linker menangani tugas-tugas kecil seperti memperbaiki referensi ke simbol global sehingga modul Anda dapat memanggil fungsi satu sama lain. Perpustakaan juga dapat ditautkan secara statis. File objek yang membentuk pustaka dikumpulkan bersama oleh pustakawan dalam file .LIB yang dicari linker untuk modul yang berisi simbol yang diperlukan. Salah satu efek dari tautan statis adalah bahwa hanya modul-modul dari perpustakaan yang digunakan oleh program yang ditautkan ke sana; modul lain diabaikan. Misalnya, pustaka matematika C tradisional mencakup banyak fungsi trigonometri. Tetapi jika Anda menautkannya dan menggunakancos()
, Anda tidak akan mendapatkan salinan kode untuk sin()
atau tan()
kecuali Anda juga memanggil fungsi itu. Untuk perpustakaan besar dengan sekumpulan fitur yang kaya, penyertaan modul secara selektif ini penting. Pada banyak platform seperti sistem tertanam, ukuran total kode yang tersedia untuk digunakan di perpustakaan bisa lebih besar dibandingkan dengan ruang yang tersedia untuk menyimpan file yang dapat dieksekusi di perangkat. Tanpa inklusi selektif, akan lebih sulit untuk mengelola detail program pembangunan untuk platform tersebut.
Namun, memiliki salinan pustaka yang sama di setiap program yang berjalan menciptakan beban pada sistem yang biasanya menjalankan banyak proses. Dengan jenis sistem memori virtual yang tepat, halaman memori yang memiliki konten identik hanya perlu ada sekali di sistem, tetapi dapat digunakan oleh banyak proses. Hal ini memberikan manfaat untuk meningkatkan peluang bahwa halaman yang berisi kode cenderung identik dengan beberapa halaman dalam sebanyak mungkin proses yang berjalan. Namun, jika program secara statis menautkan ke pustaka runtime, maka masing-masing memiliki campuran fungsi yang berbeda yang masing-masing diatur dalam memproses peta memori di lokasi yang berbeda, dan tidak banyak halaman kode yang dapat dibagikan kecuali jika program itu sendiri adalah program yang berdiri sendiri. berjalan lebih dari sekedar proses. Jadi gagasan tentang DLL memperoleh keuntungan besar lainnya.
DLL untuk pustaka berisi semua fungsinya, siap digunakan oleh program klien apa pun. Jika banyak program memuat DLL itu, mereka semua dapat berbagi halaman kodenya. Semua orang menang. (Nah, sampai Anda memperbarui DLL dengan versi baru, tapi itu bukan bagian dari cerita ini. Google DLL Neraka untuk sisi kisah itu.)
Jadi, pilihan besar pertama yang harus diambil ketika merencanakan proyek baru adalah antara hubungan dinamis dan statis. Dengan tautan statis, Anda memiliki lebih sedikit file untuk diinstal, dan Anda kebal dari pihak ketiga yang memperbarui DLL yang Anda gunakan. Namun, program Anda lebih besar, dan itu tidak cukup baik untuk ekosistem Windows. Dengan tautan dinamis, Anda memiliki lebih banyak file untuk diinstal, Anda mungkin memiliki masalah dengan pihak ketiga yang memperbarui DLL yang Anda gunakan, tetapi Anda secara umum lebih ramah terhadap proses lain di sistem.
Keuntungan besar dari DLL adalah ia dapat dimuat dan digunakan tanpa kompilasi ulang atau bahkan menautkan ulang program utama. Ini memungkinkan penyedia pustaka pihak ketiga (misalnya Microsoft dan runtime C) untuk memperbaiki bug di pustaka mereka dan mendistribusikannya. Setelah pengguna akhir menginstal DLL yang diperbarui, mereka segera mendapatkan manfaat dari perbaikan bug tersebut di semua program yang menggunakan DLL tersebut. (Kecuali itu merusak banyak hal. Lihat DLL Hell.)
Keuntungan lainnya berasal dari perbedaan antara pemuatan implisit dan eksplisit. Jika Anda melakukan upaya ekstra untuk memuat eksplisit, DLL mungkin bahkan tidak ada saat program ditulis dan diterbitkan. Ini memungkinkan mekanisme ekstensi yang dapat menemukan dan memuat plugin, misalnya.
lib /list xxx.lib
danlink /dump /linkermember xxx.lib
. Lihat pertanyaan Stack Overflow ini .