Bir DLL dosyasına bağlanma, dolaylı olarak derleme bağlantı zamanında veya çalışma zamanında açıkça gerçekleşebilir. Her iki durumda da DLL, işlemlerin bellek alanına yüklenir ve dışa aktarılan tüm giriş noktaları uygulama tarafından kullanılabilir.
Çalışma zamanında açıkça kullanılırsa, kullanmak LoadLibrary()
ve GetProcAddress()
el ile aramak gereken işlevlere işaretçileri DLL yüklenemedi ve olsun.
Program oluşturulduğunda örtük olarak bağlanırsa, program tarafından kullanılan her bir DLL dışa aktarımının saplamaları, bir içe aktarma kitaplığından programa bağlanır ve bu saplamalar, işlem başladığında EXE ve DLL yüklenirken güncellenir. (Evet, burada biraz daha basitleştirdim ...)
Bu taslakların bir yerden gelmesi gerekir ve Microsoft araç zincirinde içe aktarma kitaplığı adı verilen özel bir .LIB dosyası biçiminden gelirler . Gerekli .LIB genellikle DLL ile aynı anda oluşturulur ve DLL'den dışa aktarılan her işlev için bir saplama içerir.
Kafa karıştırıcı bir şekilde, aynı kitaplığın statik bir sürümü de .LIB dosyası olarak gönderilir. Bunları ayırmanın önemsiz bir yolu yoktur, ancak DLL'ler için içe aktarım kitaplıkları olan LIB'ler, eşleşen statik LIB'nin olacağından genellikle daha küçük (genellikle çok daha küçük) olacaktır.
GCC araç zincirini kullanırsanız, bu arada, DLL'lerinizle eşleşecek içe aktarma kitaplıklarına ihtiyacınız yoktur. Windows'a taşınan Gnu bağlayıcısının sürümü, DLL'leri doğrudan anlar ve gerekli olan çoğu saplamayı anında sentezleyebilir.
Güncelleme
Tüm somunların ve cıvataların gerçekte nerede olduğunu ve gerçekte neler olduğunu bilmeye direnemiyorsanız, MSDN'de her zaman yardımcı olacak bir şeyler vardır. Matt Pietrek'in Win32 Taşınabilir Yürütülebilir Dosya Biçimine Derinlemesine Bir Bakış adlı makalesi , EXE dosyasının biçimine ve nasıl yüklenip çalıştırılacağına dair eksiksiz bir genel bakış niteliğindedir. Hatta, ilk olarak MSDN Magazine'de göründüğünden beri .NET ve daha fazlasını kapsayacak şekilde güncellendi. 2002.
Ayrıca, bir program tarafından tam olarak hangi DLL'lerin kullanıldığını öğrenmek yararlı olabilir. Bunun için kullanılan araç Dependency Walker, aka ports.exe'dir. Bir sürümü Visual Studio'da bulunur, ancak en son sürümü yazarından http://www.dependencywalker.com/ adresinden edinilebilir . Bağlantı zamanında belirtilen tüm DLL'leri tanımlayabilir (hem erken yükleme hem de gecikmeli yükleme) ve ayrıca programı çalıştırabilir ve çalışma zamanında yüklediği ek DLL'leri izleyebilir.
Güncelleme 2
Yeniden okurken açıklığa kavuşturmak ve MSDN ile tutarlılık için sanat koşullarını örtük ve açık bir şekilde kullanmak için önceki metnin bazılarını yeniden ifade ettim .
Bu nedenle, kütüphane işlevlerinin bir program tarafından kullanılmak üzere sunulması için üç yolumuz var. O zaman aşikar olan takip sorusu şudur: "Hangi yolu nasıl seçerim?"
Statik bağlantı, programın büyük bir kısmının nasıl bağlantılı olduğudur. Tüm nesne dosyalarınız listelenir ve birleştirici tarafından EXE dosyasında toplanır. Yol boyunca bağlayıcı, modüllerinizin birbirlerinin işlevlerini çağırabilmesi için küresel sembollere referansları düzeltmek gibi küçük işleri halleder. Kitaplıklar ayrıca statik olarak bağlanabilir. Kütüphaneyi oluşturan nesne dosyaları, bir kütüphaneci tarafından bir .LIB dosyasında toplanır ve linker gerekli olan sembolleri içeren modülleri arar. Statik bağlantının bir etkisi, yalnızca program tarafından kullanılan kitaplıktaki modüllerin ona bağlanmasıdır; diğer modüller dikkate alınmaz. Örneğin, geleneksel C matematik kitaplığı birçok trigonometri işlevi içerir. Ama buna karşı bağlar ve kullanırsanızcos()
, Sizin için bir kod kopyasıyla sonunda yok sin()
ya tan()
da bu işlevleri denir sürece. Zengin özelliklere sahip büyük kitaplıklar için, modüllerin bu seçici şekilde dahil edilmesi önemlidir. Gömülü sistemler gibi birçok platformda, kitaplıkta kullanılabilen toplam kod boyutu, cihazda bir yürütülebilir dosyayı depolamak için mevcut alana kıyasla büyük olabilir. Seçici dahil etme olmadan, bu platformlar için program oluşturma ayrıntılarını yönetmek daha zor olurdu.
Bununla birlikte, çalışan her programda aynı kütüphanenin bir kopyasına sahip olmak, normalde çok sayıda işlem çalıştıran bir sisteme yük oluşturur. Doğru türden sanal bellek sistemiyle, aynı içeriğe sahip bellek sayfalarının sistemde yalnızca bir kez bulunması gerekir, ancak birçok işlem tarafından kullanılabilir. Bu, kod içeren sayfaların, mümkün olduğu kadar çok sayıda diğer çalışan işlemdeki bazı sayfalarla aynı olma olasılığını artırmak için bir fayda sağlar. Ancak, programlar çalışma zamanı kitaplığına statik olarak bağlanırsa, her biri farklı konumlarda bellek haritasını işleyen her biri farklı bir işlev karışımına sahiptir ve kendi başına bir program olmadığı sürece pek çok paylaşılabilir kod sayfası yoktur. süreçten daha fazlasını çalıştırın. Böylece bir DLL fikri başka, büyük bir avantaj kazandı.
Bir kitaplık için DLL, herhangi bir istemci programı tarafından kullanıma hazır olan tüm işlevlerini içerir. Birçok program bu DLL dosyasını yüklerse, hepsi kod sayfalarını paylaşabilir. Herkes kazanır. (Bir DLL dosyasını yeni sürümle güncelleyene kadar, ancak bu hikayenin bir parçası değil. Hikayenin bu tarafı için Google DLL Hell.)
Dolayısıyla, yeni bir proje planlarken yapılacak ilk büyük seçim, dinamik ve statik bağlantı arasındadır. Statik bağlantı ile, yüklemek için daha az dosyanız olur ve kullandığınız bir DLL dosyasını üçüncü tarafların güncellemelerine karşı bağışıksınızdır. Bununla birlikte, programınız daha büyük ve Windows ekosisteminin pek de iyi vatandaşı değil. Dinamik bağlantı ile, yüklemeniz gereken daha fazla dosya vardır, kullandığınız bir DLL dosyasını üçüncü bir tarafın güncellemesiyle ilgili sorunlar yaşayabilirsiniz, ancak genellikle sistemdeki diğer işlemlere karşı daha dostça davranırsınız.
Bir DLL'nin en büyük avantajı, ana programı yeniden derlemeden ve hatta yeniden bağlamadan yüklenip kullanılabilmesidir. Bu, bir üçüncü taraf kitaplık sağlayıcısının (örneğin, Microsoft ve C çalışma zamanını düşünün) kitaplıklarındaki bir hatayı düzeltmesine ve dağıtmasına izin verebilir. Bir son kullanıcı güncellenmiş DLL'yi yükledikten sonra, o DLL'yi kullanan tüm programlarda bu hata düzeltmesinden hemen faydalanır. (Bir şeyleri bozmadığı sürece. Bkz. DLL Cehennemi.)
Diğer avantaj, örtük ve açık yükleme arasındaki ayrımdan gelir. Ekstra açık yükleme çabasına girerseniz, DLL, program yazılırken ve yayınlanırken bile mevcut olmayabilir. Bu, örneğin eklentileri bulabilen ve yükleyebilen uzantı mekanizmalarına izin verir.
lib /list xxx.lib
velink /dump /linkermember xxx.lib
. Bu Stack Overflow sorusuna bakın .