DLL nedir?
Bu makalede, dinamik bağlantı kitaplığının (DLL) ne olduğu ve DLL kullandığınızda oluşabilecek çeşitli sorunlar açıklanmaktadır. Ayrıca kendi DLL'lerinizi geliştirirken dikkate almanız gereken bazı gelişmiş sorunlar da açıklanır.
Şunlar için geçerlidir: Windows 10, tüm sürümler
Orijinal KB numarası: 815065
Özet
Bir DLL'nin ne olduğunu açıklarken, bu makalede dinamik bağlama yöntemleri, DLL bağımlılıkları, DLL giriş noktaları, DLL işlevlerini dışarı aktarma ve DLL sorun giderme araçları açıklanmaktadır.
Bu makale, Microsoft .NET Framework derlemeleri ile DLL'lerin üst düzey bir karşılaştırması ile tamamlanır.
Windows işletim sistemleri için işletim sisteminin işlevselliğinin çoğu DLL tarafından sağlanır. Ayrıca, bu Windows işletim sistemlerinden birinde bir program çalıştırdığınızda, programın işlevselliğinin çoğu DLL'ler tarafından sağlanabilir. Örneğin, bazı programlar birçok farklı modül içerebilir ve programın her modülü DLL'lerde yer alır ve dağıtılır.
DLL'lerin kullanımı, kodun modüler hale gelmesini, kodun yeniden kullanılmasını, verimli bellek kullanımını ve disk alanının azaltılmasını desteklemeye yardımcı olur. Bu nedenle, işletim sistemi ve programlar daha hızlı yüklenir, daha hızlı çalışır ve bilgisayarda daha az disk alanı kullanır.
Bir program DLL kullandığında, bağımlılık olarak adlandırılan bir sorun programın çalışmamasına neden olabilir. Bir program DLL kullandığında, bir bağımlılık oluşturulur. Başka bir program bu bağımlılığın üzerine yazar ve bozarsa özgün program başarıyla çalışmayabilir.
.NET Framework'ün tanıtılmasıyla birlikte, bağımlılık sorunlarının çoğu derlemeler kullanılarak ortadan kaldırılmıştır.
Daha fazla bilgi
DLL, aynı anda birden fazla program tarafından kullanılabilen kod ve veriler içeren bir kitaplıktır. Örneğin, Windows işletim sistemlerinde Comdlg32 DLL, ortak iletişim kutusuyla ilgili işlevleri gerçekleştirir. Her program, bir Aç iletişim kutusu uygulamak için bu DLL'de yer alan işlevselliği kullanabilir. Kodun yeniden kullanılmasını ve verimli bellek kullanımını yükseltmeye yardımcı olur.
Bir DLL kullanılarak, bir program ayrı bileşenler halinde modüler hale getirilebilir. Örneğin, bir muhasebe programı modül modül satılabilir. Bu modül kurulmuşsa her modül çalışma zamanında ana programa yüklenebilir. Modüller ayrı olduğundan, programın yükleme süresi daha hızlıdır. Ayrıca bir modül yalnızca bu işlev istendiğinde yüklenir.
Ayrıca güncelleştirmelerin, programın diğer bölümlerini etkilemeden her modüle uygulanması daha kolaydır. Örneğin, bir bordro programınız olabilir ve vergi oranları her yıl değişir. Bu değişiklikler bir DLL'ye yalıtıldığında, programın tamamını yeniden derlemenize veya yüklemenize gerek kalmadan bir güncelleştirme uygulayabilirsiniz.
Aşağıdaki listede, Windows işletim sistemlerinde DLL olarak uygulanan dosyalardan bazıları açıklanmaktadır:
ActiveX Denetimleri (.ocx) dosyaları
ActiveX denetimine bir örnek, takvimden bir tarih seçmenize olanak tanıyan bir takvim denetimidir.
Denetim Masası (.cpl) dosyaları
.cpl dosyasına bir örnek, Denetim Masası'nda bulunan bir öğedir. Her öğe özel bir DLL'dir.
Cihaz sürücüsü (.drv) dosyaları
Cihaz sürücüsüne bir örnek, yazıcıya yazdırmayı denetleyen bir yazıcı sürücüsüdür.
DLL avantajları
Aşağıdaki listede, bir program DLL kullandığında sağlanan avantajlardan bazıları açıklanmaktadır:
Daha az kaynak kullanır
Birden çok program aynı işlev kitaplığını kullandığında DLL, diske ve fiziksel belleğe yüklenen kodun yinelenme oranını azaltabilir. Yalnızca ön planda çalışan programın değil, aynı zamanda Windows işletim sisteminde çalışan diğer programların performansını da büyük ölçüde etkileyebilir.
Modüler mimariyi destekler
Bir DLL, modüler programlar geliştirmeye yardımcı olur. Birden çok dil sürümü gerektiren büyük programlar veya modüler mimari gerektiren bir program geliştirmenize yardımcı olur. Modüler bir program örneği, çalışma zamanında dinamik olarak yüklenebilen birçok modülün bulunduğu bir muhasebe programıdır.
Dağıtım ve yüklemeyi kolaylaştırır
DLL içindeki bir işlev bir güncelleştirmeye veya düzeltmeye ihtiyaç duyduğunda, DLL'nin dağıtımı ve yüklemesi, programın DLL ile yeniden bağlanmasını gerektirmez. Ayrıca, birden çok program aynı DLL'yi kullanıyorsa, birden çok programın hepsi güncelleştirmeden veya düzeltmeden yararlanacaktır. Bu sorun, düzenli olarak güncelleştirme veya düzeltme alan bir üçüncü taraf DLL kullandığınızda daha sık ortaya çıkabilir.
DLL bağımlılıkları
Bir program veya DLL başka bir DLL'de DLL işlevi kullandığında, bir bağımlılık oluşturulur. Program artık bağımsız değildir ve bağımlılık bozulursa program sorunlarla karşılaşabilir. Örneğin, aşağıdaki eylemlerden biri gerçekleşirse program çalışmayabilir:
- Bağımlı DLL yeni bir sürüme yükseltilirse.
- Bağımlı DLL düzeltilirse.
- Önceki bir sürüm bağımlı DLL'nin üzerine yazılırsa.
- Bağımlı DLL bilgisayardan kaldırılırsa.
Bu eylemler DLL çakışmaları olarak bilinir. Geriye dönük uyumluluk zorlanmazsa, program başarıyla çalışmayabilir.
Aşağıdaki listede, bağımlılık sorunlarını en aza indirmeye yardımcı olmak için Windows 2000 ve sonraki Windows işletim sistemlerinde getirilen değişiklikler açıklanmaktadır:
Windows Dosya Koruması
Windows Dosya Koruması'nda işletim sistemi, sistem DLL'lerinin yetkisiz bir aracı tarafından güncelleştirilmesini veya silinmesini engeller. Bir program yüklemesi sistem DLL'si olarak tanımlanan bir DLL'yi kaldırmaya veya güncelleştirmeye çalıştığında, Windows Dosya Koruması geçerli bir dijital imza arar.
Özel DLL'ler
Özel DLL'ler, bir programı paylaşılan DLL'lerde yapılan değişikliklerden yalıtmanıza olanak sağlar. Özel DLL'ler, program tarafından kullanılan DLL sürümünü zorlamak için sürüme özgü bilgileri veya boş
.localdosyasını kullanır. Özel DLL'leri kullanmak için, program kök klasöründe DLL'lerinizi bulun. Ardından, yeni programlar için sürüme özgü bilgileri DLL'ye ekleyin. Eski programlar için boş bir
.localdosyası kullanın. Her yöntem işletim sistemine, program kök klasöründe bulunan özel DLL'leri kullanmasını söyler.
DLL sorun giderme araçları
DLL sorunlarını gidermenize yardımcı olacak çeşitli araçlar mevcuttur. Aşağıdaki araçlar bu araçlardan bazılarıdır.
Bağımlılık Denetçisi
Bağımlılık Denetçisi aracı, bir program tarafından kullanılan tüm bağımlı DLL'leri özyinelemeli olarak tarayabilir. Bağımsızlık Denetçisinde bir program açtığınızda Bağımsızlık Denetçisi aşağıdaki denetimleri yapar:
- Bağımlılık Denetçisi eksik DLL'leri denetler.
- Bağımlılık Denetçisi, geçerli olmayan program dosyalarını veya DLL'leri denetler.
- Bağımlılık Denetçisi, içeri aktarma işlevlerinin ve dışarı aktarma işlevlerinin eşleşip eşleşmediğini denetler.
- Bağımlılık Denetçisi döngüsel bağımlılık hatalarını denetler.
- Bağımlılık Denetçisi, farklı bir işletim sistemine yönelik olduğu için geçerli olmayan modülleri denetler.
Bağımlılık Denetçisini kullanarak, bir programın kullandığı tüm DLL'leri belgeleyebilirsiniz. Gelecekte oluşabilecek DLL sorunlarını önlemeye ve düzeltmeye yardımcı olabilir. Bağımlılık Denetçisi, Visual Studio 6.0'yı yüklediğinizde aşağıdaki dizinde bulunur:
drive\Program Files\Microsoft Visual Studio\Common\Tools
DLL Evrensel Sorun Çözücü
DLL Evrensel Sorun Çözücü (DUPS) aracı, DLL bilgilerini denetlemek, karşılaştırmak, belgelemek ve görüntülemek için kullanılır. Aşağıdaki listede DUPS aracını oluşturan yardımcı programlar açıklanmaktadır:
Dlister.exe
Bu yardımcı program bilgisayardaki tüm DLL'leri numaralandırır ve bilgileri bir metin dosyasına veya veritabanı dosyasına kaydeder.
Dcomp.exe
Bu yardımcı program, iki metin dosyasında listelenen DLL'leri karşılaştırır ve farkları içeren üçüncü bir metin dosyası üretir.
Dtxt2DB.exe
Bu yardımcı program, Dlister.exe yardımcı programı ve Dcomp.exe yardımcı programı kullanılarak oluşturulan metin dosyalarını dllHell veritabanına yükler.
DlgDtxt2DB.exe
Bu yardımcı program, Dtxt2DB.exe yardımcı programının grafik kullanıcı arabirimi (GUI) sürümünü sağlar.
DLL Yardım veritabanı
DLL Yardım veritabanı, Microsoft yazılım ürünleri tarafından yüklenen DLL'lerin belirli sürümlerini bulmanıza yardımcı olur.
DLL geliştirme
Bu bölümde, kendi DLL'lerinizi geliştirirken dikkate almanız gereken sorunlar ve gereksinimler açıklanmaktadır.
DLL türleri
Bir uygulamada bir DLL yüklediğinizde, iki bağlama yöntemi dışarı aktarılan DLL işlevlerini çağırmanıza olanak sağlar. İki bağlama yöntemi, yükleme zamanı dinamik bağlama ve çalışma zamanı dinamik bağlamadır.
Yükleme zamanı dinamik bağlama
Yükleme zamanı dinamik bağlamada bir uygulama, dışarı aktarılan DLL işlevlerine yerel işlevler gibi açık çağrılar yapar. Yükleme zamanı dinamik bağlamayı kullanmak için uygulamayı derleyip bağladığınızda bir üst bilgi (.h) dosyası ve bir içeri aktarma kitaplığı (.lib) dosyası sağlayın. Bunu yaptığınızda bağlayıcı, sisteme DLL'yi yüklemek ve dışarı aktarılan DLL işlev konumlarını yükleme zamanında çözümlemek için gereken bilgileri sağlar.
Çalışma zamanı dinamik bağlama
Çalışma zamanı dinamik bağlamada bir uygulama, DLL'yi çalışma zamanında yüklemek için
LoadLibrary işlevini veya
LoadLibraryEx işlevini çağırır. DLL başarıyla yüklendikten sonra, çağırmak istediğiniz dışarı aktarılan DLL işlevinin adresini almak için
GetProcAddress işlevini kullanırsınız. Çalışma zamanı dinamik bağlamayı kullandığınızda, bir içeri aktarma kitaplığı dosyasına ihtiyacınız yoktur.
Aşağıdaki listede, yükleme zamanı dinamik bağlamanın ne zaman kullanılacağına ve çalışma zamanı dinamik bağlamanın ne zaman kullanılacağına ilişkin uygulama ölçütleri açıklanmaktadır:
Başlangıç performansı
Uygulamanın ilk başlangıç performansı önemliyse çalışma zamanı dinamik bağlamayı kullanmalısınız.
Kullanım kolaylığı
Yükleme zamanı dinamik bağlamada, dışarı aktarılan DLL işlevleri yerel işlevler gibidir. Bu, bu işlevleri çağırmanızı kolaylaştırır.
Uygulama mantığı
Çalışma zamanı dinamik bağlamada, bir uygulama gerektiğinde farklı modülleri yüklemek için dallanabilir. Birden çok dil sürümü geliştirirken bu önemlidir.
DLL giriş noktası
Bir DLL oluşturduğunuzda, isteğe bağlı olarak bir giriş noktası işlevi belirtebilirsiniz. Giriş noktası işlevi, işlemler veya iş parçacıkları kendilerini DLL'ye bağladığında veya kendilerini DLL'den ayırdığında çağrılır. DLL'nin gerektirdiği şekilde veri yapılarını başlatmak veya veri yapılarını yok etmek için giriş noktası işlevini kullanabilirsiniz. Ayrıca, uygulama çok iş parçacıklıysa, giriş noktası işlevindeki her iş parçacığına özel bellek ayırmak için iş parçacığı yerel depolamasını (TLS) kullanabilirsiniz. Aşağıdaki kod, DLL giriş noktası işlevinin bir örneğidir.
BOOL APIENTRY DllMain(
HANDLE hModule,// Handle to DLL module
DWORD ul_reason_for_call,// Reason for calling function
LPVOID lpReserved ) // Reserved
{
switch ( ul_reason_for_call )
{
case DLL_PROCESS_ATTACHED: // A process is loading the DLL.
break;
case DLL_THREAD_ATTACHED: // A process is creating a new thread.
break;
case DLL_THREAD_DETACH: // A thread exits normally.
break;
case DLL_PROCESS_DETACH: // A process unloads the DLL.
break;
}
return TRUE;
}
Giriş noktası işlevi FALSE değeri döndürdüğünde, yükleme zamanı dinamik bağlama kullanıyorsanız uygulama başlatılmaz. Çalışma zamanı dinamik bağlama kullanıyorsanız yalnızca tek DLL yüklenmeyecektir.
Giriş noktası işlevi yalnızca basit başlatma görevlerini gerçekleştirmeli ve diğer DLL yükleme veya sonlandırma işlevlerini çağırmamalıdır. Örneğin, giriş noktası işlevinde,
LoadLibrary işlevini veya
LoadLibraryEx işlevini doğrudan veya dolaylı olarak çağırmamalısınız. Ayrıca, işlem sonlandırılırken
FreeLibrary işlevini çağırmamalısınız.
Not
Çok iş parçacıklı uygulamalarda, olası veri bozulmalarını önlemek için DLL genel verilerine erişimin eşitlendiğinden (iş parçacığı güvenli) emin olun. Bunu yapmak için TLS kullanarak her iş parçacığı için benzersiz veriler sağlayın.
DLL işlevlerini dışarı aktarma
DLL işlevlerini dışarı aktarmak için dışarı aktarılan DLL işlevlerine bir işlev anahtar sözcüğü ekleyebilir veya dışarı aktarılan DLL işlevlerini listeleyen bir modül tanımı (.def) dosyası oluşturabilirsiniz.
İşlev anahtar sözcüğünü kullanmak için dışarı aktarmak istediğiniz her işlevi aşağıdaki anahtar sözcükle bildirmeniz gerekir:
__declspec(dllexport)
Uygulamada dışarı aktarılan DLL işlevlerini kullanmak için içeri aktarmak istediğiniz her işlevi aşağıdaki anahtar sözcükle bildirmeniz gerekir:
__declspec(dllimport)
Genellikle, dışarı aktarma deyimini ve
import deyimini ayırmak için bir tanımlama deyimi ve bir
ifdef deyimi olan bir üst bilgi dosyası kullanabilirsiniz.
Dışarı aktarılan DLL işlevlerini bildirmek için bir modül tanım dosyası da kullanabilirsiniz. Modül tanım dosyası kullandığınızda, dışarı aktarılan DLL işlevlerine işlev anahtar sözcüğünü eklemeniz gerekmez. Modül tanımı dosyasında, DLL için
LIBRARY deyimini ve
EXPORTS deyimini bildirirsiniz. Aşağıdaki kod, bir tanım dosyası örneğidir.
// SampleDLL.def
//
LIBRARY "sampleDLL"
EXPORTS HelloWorld
Örnek DLL ve uygulama
Visual C++ 6.0'da, ya Win32 Dynamic-Link Kitaplığı proje türünü ya da MFC AppWizard (dll) proje türünü seçerek bir DLL oluşturabilirsiniz.
Aşağıdaki kod, Win32 Dynamic-Link Kitaplığı proje türü kullanılarak Visual C++ ile oluşturulmuş bir DLL örneğidir.
// SampleDLL.cpp
//
#include "stdafx.h"
#define EXPORTING_DLL
#include "sampleDLL.h"
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved
)
{
return TRUE;
}
void HelloWorld()
{
MessageBox( NULL, TEXT("Hello World"), TEXT("In a DLL"), MB_OK);
}
// File: SampleDLL.h
//
#ifndef INDLL_H
#define INDLL_H
#ifdef EXPORTING_DLL
extern __declspec(dllexport) void HelloWorld();
#else
extern __declspec(dllimport) void HelloWorld();
#endif
#endif
Aşağıdaki kod, SampleDLL DLL'sinde dışarı aktarılan DLL işlevini çağıran bir Win32 Uygulaması proje örneğidir.
// SampleApp.cpp
//
#include "stdafx.h"
#include "sampleDLL.h"
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HelloWorld();
return 0;
}
Not
Yükleme zamanı dinamik bağlamada, SampleDLL projesini oluştururken oluşturulan SampleDLL.lib içeri aktarma kitaplığını bağlamanız gerekir.
Çalışma zamanı dinamik bağlamada, SampleDLL.dll dışarı aktarılan DLL işlevini çağırmak için aşağıdaki koda benzer bir kod kullanırsınız.
...
typedef VOID (*DLLPROC) (LPTSTR);
...
HINSTANCE hinstDLL;
DLLPROC HelloWorld;
BOOL fFreeDLL;
hinstDLL = LoadLibrary("sampleDLL.dll");
if (hinstDLL != NULL)
{
HelloWorld = (DLLPROC) GetProcAddress(hinstDLL, "HelloWorld");
if (HelloWorld != NULL)
(HelloWorld);
fFreeDLL = FreeLibrary(hinstDLL);
}
...
SampleDLL uygulamasını derleyip bağladığınızda, Windows işletim sistemi SampleDLL DLL'yi şu sırayla aşağıdaki konumlarda arar:
Uygulama klasörü
Geçerli klasör
Windows sistem klasörü
Not
GetSystemDirectory işlevi, Windows sistem klasörünün yolunu döndürür.
Windows klasörü
Not
GetWindowsDirectory işlevi Windows klasörünün yolunu döndürür.
.NET Framework derlemesi
.NET ve .NET Framework'ün kullanıma sunulmasıyla, DLL'lerle ilişkili sorunların çoğu derlemeler kullanılarak ortadan kaldırılmıştır. Derleme, .NET ortak dil çalışma zamanı (CLR) denetimi altında çalışan mantıksal bir işlev birimidir. Derleme, fiziksel olarak .dll dosyası veya .exe dosyası olarak bulunur. Ancak, dahili olarak bir derleme Microsoft Win32 DLL'den farklıdır.
Derleme dosyası bir derleme bildirimi, tür meta verisi, Microsoft ara dil (MSIL) kodu ve diğer kaynakları içerir. Derleme bildirimi, bir derlemenin kendi kendini açıklayıcı olması için gereken tüm bilgileri sağlayan derleme meta verisini içerir. Derleme bildirimine aşağıdaki bilgiler dahil edilir:
- Derleme adı
- Sürüm bilgileri
- Kültür bilgileri
- Tanımlayıcı ad bilgileri
- Dosyaların derleme listesi
- Tür başvurusu bilgileri
- Başvurulan ve bağımlı derleme bilgileri
Derlemede yer alan MSIL kodu doğrudan yürütülemez. Bunun yerine, MSIL kod yürütme CLR aracılığıyla yönetilir. Varsayılan olarak, bir derleme oluşturduğunuzda derleme uygulamaya özeldir. Paylaşılan derleme oluşturmak için derlemeye tanımlayıcı bir ad atamanız ve sonra derlemeyi genel derleme önbelleğinde yayımlamanız gerekir.
Aşağıdaki listede, derlemelerin bazı özellikleri Win32 DLL'lerinin özellikleriyle karşılaştırmalı olarak açıklanmaktadır:
Kendi kendini açıklayıcı
Bir derleme oluşturduğunuzda, CLR'nin derlemeyi çalıştırması için gereken tüm bilgiler derleme bildiriminde yer alır. Derleme bildirimi, bağımlı derlemelerden oluşan bir liste içerir. Bu nedenle, CLR uygulamada kullanılan tutarlı bir derleme kümesini tutabilir. Win32 DLL'lerinde, paylaşılan DLL'leri kullandığınızda uygulamada kullanılan bir dizi DLL arasındaki tutarlılığı sürdüremezsiniz.
Sürüm oluşturma
Derleme bildiriminde sürüm bilgileri CLR tarafından kaydedilir ve zorlanır. Ayrıca, sürüm ilkeleri sürüme özgü kullanımı zorlamanıza olanak verir. Win32 DLL'lerinde sürüm oluşturma, işletim sistemi tarafından zorlanamaz. DLL'lerin geriye dönük olarak uyumlu olduğundan emin olmanız gerekir.
Yan yana dağıtım
Derlemeler yan yana dağıtımı destekler. Bir uygulama derlemenin bir sürümünü, başka bir uygulama ise derlemenin farklı bir sürümünü kullanabilir. Windows 2000'den başlayarak, uygulama klasöründe DLL'lerin bulunmasıyla yan yana dağıtım desteklenir. Ayrıca Windows Dosya Koruması, yetkisiz bir aracı tarafından sistem DLL'lerinin üzerine yazılmasını veya değiştirilmesini önler.
Bağımsız olma ve yalıtım
Derleme kullanılarak geliştirilen bir uygulama, bilgisayarda çalışan diğer uygulamalardan bağımsız ve yalıtılmış olabilir. Bu özellik, sıfır etkili yüklemeler oluşturmanıza yardımcı olur.
Yürütme
Derleme, derleme bildiriminde sağlanan ve CLR tarafından denetlenen güvenlik izinleri altında çalıştırılır.
Dilden bağımsız
Derleme, desteklenen .NET dillerinden herhangi biri kullanılarak geliştirilebilir. Örneğin, Microsoft Visual C# içinde bir derleme geliştirebilir ve sonra derlemeyi bir Visual Basic .NET projesinde kullanabilirsiniz.
Veri toplama
Microsoft destek ekibinden yardım almaya ihtiyacınız varsa Dağıtımla ilgili sorunlar için TSS kullanarak bilgi toplama bölümünde belirtilen adımları izleyerek bilgi toplamanızı öneririz.