Aracılığıyla paylaş


Hangi Bağlama Yöntemini Kullanacağınızı Belirleme

İki tür bağlama var: dolaylı olarak bağlama ve açıkça bağlama.

Dolaylı Olarak Bağlama

Dolaylı olarak bağlama, bir uygulamanın kodu dışarı aktarılmış DLL işlevi çağırdığında meydana gelir. Çağıran çalıştırılabilirin kaynak kodu derlendiğinde veya birleştirildiğinde, DLL işlev çağrısı nesne kodunda dış işlev başvurusu oluşturur. Bu dış başvuruyu çözümlemek için, DLL'in oluşturucusunun sağladığı içeri aktarma kitaplığıyla (.lib dosyası) uygulama bağlanmalıdır.

İçeri aktarma kitaplığı sadece DLL'i yüklemek ve DLL'deki işlevlere olan çağrıları uygulamak için olan kodu içerir. İçeri aktarma kitaplığındaki bir dış işlevi bulma, bu işlevin kodunun DLL'de olduğunu bağlayıcıya bildirir. DLL'lere olan dış başvuruları çözümlemek için; bağlayıcı çalıştırılabilir dosyaya sadece, işlem başladığında DLL kodunu nerde bulacağını sisteme söyleyen bilgiyi ekler.

Sistem dinamik olarak bağlanmış başvurular içeren bir program başlattığında, gerekli DLL'leri bulmak için programın çalıştırılabilir dosyasındaki bilgiyi kullanır. Eğer DLL'i bulamazsa, sistem işlemi sonlandırır ve hatayı raporlayan iletişim kutusu görüntüler. Diğer durumda, sistem DLL modüllerini işlemin adres uzayına eşler.

Eğer DLL'lerden herhangi birinde giriş noktası işlevi (başlangıç ve sonlandırma kodu için) varsa, işletim sistemi işlevi çağırır. Giriş noktası işlevine geçirilen parametrelerden biri, DLL'in işleve eklendiğini gösteren bir kod belirtir. Girişi noktası işlevi TRUE dönmezse, sistem işlemi sonlandırır ve hatayı raporlar.

Son olarak, sistem DLL işlevlerinin başlama adreslerini sağlamak için işlemin çalıştırılabilir kodunu değiştirir.

Programın geri kalan kodu gibi, DLL kodu işlem bağladığında işlemin adres uzayına eşlenir ve sadece gerektiğinde belleğe yüklenir. Sonuç olarak, Windows'un daha önceki versiyonlarında yüklemeyi denetlemek için .def dosyaları tarafından kullanılan PRELOAD ve LOADONCALL kod özniteliklerinin artık bir anlamı yoktur.

Açıkça Bağlama

Çoğu uygulama dolaylı olarak bağlamayı kullanır çünkü kullanılabilecek en kolay bağlama yöntemidir. Ancak, açıkça bağlama'nın gerekli olduğu durumlar vardır. Açıkça bağlama kullanmak için bazı ortak sebepler şunlardır:

  • Uygulama çalışma zamanına kadar yüklemesi gereken DLL'in ismini bilmediğinde. Örneğin, uygulamanın DLL'in ismini ve dışarı aktarılan işlevleri yapılandırma dosyasından alması gerekebilir.

  • DLL işlem başlangıcında bulunmazsa dolaylı olarak bağlama kullanan işlem işletim sistemi tarafından sonlandırılır. Açıkça bağlama kullanan işlem bu durumda sonlandırılmaz ve hatadan kurtarmayı dener. Örneğin, işlem kullanıcıyı hatayla ilgili uyarır ve kullanıcıya başka bir DLL yolu belirttirir.

  • Eğer dolaylı olarak bağlama kullanan bir işlemin bağlı olduğu DLL'lerden herhangi birinin başarısız olan DllMain işlevi varsa, bu işlem de sonlandırılır. Açıkça bağlama kullanan işlem bu durumda sonlandırılmaz.

  • Çok fazla DLL'e dolaylı olarak bağlı olan bir uygulama başlarken yavaş olabilir çünkü uygulama yüklenirken Windows bütün DLL'leri yükler. Başlangıç başarımını artırmak için; uygulama, yüklemeden hemen sonra gerekli olan DLL'lere dolaylı olarak bağlanıp, diğer DLL'lere gerektiğinde açıkça bağlanmak için bekleyebilir.

  • Açıkça bağlama, uygulamanın içeri aktarma kitaplığıyla bağlanma gerekliliğini kaldırır. Eğer DLL'deki değişiklikler dışarı aktarma sırasında değişikliğe sebep olursa, açıkça bağlama kullanan uygulamalar yeniden bağlanmak zorunda kalmaz (GetProcAddress'i sıralı değer yerine işlev ismiyle çağırdığı varsayılıyor), ancak dolaylı olarak bağlama kullanan uygulamalar yeni içeri aktarma kitaplığına yeniden bağlanmak zorundadırlar.

Aşağıda açıkça bağlama ile ilgili bilinmesi gereken iki tehlike vardır:

  • DLL'in DllMain giriş noktası işlevi varsa, işletim sistemi, LoadLibrary'i çağıran iş parçacığının bağlamında işlevi çağırır. Eğer DLL zaten bir işleme eklenmişse; önceki LoadLibrary çağrısına karşılık gelen FreeLibrary işlevi çağrısı olmadığından giriş noktası işlevi çağrılmaz. Eğer DLL her işlem iş parçacığını başlatmak için DllMain işlevi kullanıyorsa açıkça bağlama sorunlara yol açabilir çünkü, LoadLibrary (veya AfxLoadLibrary) çağrıldığında var olan iş parçacıkları başlatılmaz.

  • Eğer DLL statik uzantılı verileri __declspec(thread) olarak bildirirse, açıkça bağlanmışsa koruma hatalarına sebep olabilir. DLL LoadLibrary ile yüklendikten sonra, kod bu veriye her başvurduğunda DLL koruma hatasına sebep olur. (Statik uzantılı veriler hem genel hem yerel statik öğeleri içerir.) Bu sebeple, DLL oluşturduğunuzda, ya yerel iş parçacığı depolama kullanımından kaçınmalısınız veya DLL kullanıcılarını olası tehlikelere karşı uyarmalısınız (dinamik yüklemeyi denemeleri durumunda).

Ne yapmak istiyorsunuz?

Hangi konu hakkında daha fazla bilgi edinmek istiyorsunuz?

Ayrıca bkz.

Kavramlar

Bir dll bir yürütülebilir dosya bağlama