Dinamik bağlantı kitaplığı - Dynamic-link library

Dinamik bağlantı kitaplığı
Dll png.png
Dosya adı uzantısı
.dll
İnternet medya türü
application/vnd.microsoft.portable-executable
Tekdüzen Tip Tanımlayıcısı (UTI) com.microsoft.windows-dinamik-bağlantı-kütüphanesi
sihirli sayı MZ
Tarafından geliştirilmiş Microsoft
için konteyner Paylaşılan kitaplık

Dinamik bağlantı kitaplığı ( DLL ), Microsoft'un Microsoft Windows ve OS/2 işletim sistemlerinde paylaşılan kitaplık konseptinin uygulamasıdır . Bu kitaplıklar genellikle , ( ActiveX denetimlerini içeren kitaplıklar için ) veya (eski sistem sürücüleri için ) dosya uzantısına sahiptir . DLL'lerin dosya biçimleri, Windows EXE dosyalarıyla aynıdır - yani, 32-bit ve 64-bit Windows için Taşınabilir Yürütülebilir Dosya (PE) ve 16-bit Windows için Yeni Yürütülebilir Dosya (NE) . EXE'lerde olduğu gibi, DLL'ler herhangi bir kombinasyonda kod , veri ve kaynaklar içerebilir. DLLOCXDRV

DLL ile aynı dosya biçimine sahip, ancak farklı dosya uzantılarına sahip ve muhtemelen yalnızca kaynak bölümlerini içeren veri dosyalarına kaynak DLL'leri denilebilir . Böyle bir DLL örnekleri simgesi kütüphaneler , bazen uzantıya sahip ve yazı tipi dosyaları, uzantıları olan ve . ICLFONFOT

Arka plan

Microsoft Windows'un ilk sürümleri, programları tek bir adres alanında birlikte çalıştırıyordu . Her programın CPU'yu diğer programlara vererek işbirliği yapması gerekiyordu, böylece grafik kullanıcı arayüzü (GUI) çoklu görev yapabilir ve maksimum düzeyde yanıt verebilirdi. Tüm işletim sistemi düzeyindeki işlemler, temel alınan işletim sistemi tarafından sağlandı: MS-DOS . Tüm üst düzey hizmetler, Windows Kitaplıkları "Dinamik Bağlantı Kitaplığı" tarafından sağlandı. Çizim API'si , Grafik Aygıt Arabirimi (GDI), GDI.EXEkullanıcı arabirimi USER.EXE. DOS üzerindeki bu ekstra katmanların, yalnızca Windows'un bir megabayttan daha az RAM'e sahip bir makinede çalışmasını sağlamak için değil, programların birbirleriyle işbirliği yapmasını sağlamak için çalışan tüm Windows programları arasında paylaşılması gerekiyordu. GDI'daki kod, çizim komutlarını belirli cihazlardaki işlemlere çevirmek için gerekliydi. Ekranda, çerçeve arabelleğindeki pikselleri değiştirmesi gerekiyordu. Bir yazıcıya çizim yaparken, API çağrılarının bir yazıcıya yapılan isteklere dönüştürülmesi gerekiyordu. Sınırlı sayıda aygıt için ( Renkli Grafik Bağdaştırıcısı ekranı, HP LaserJet Yazıcı Komut Dili gibi ) sabit kodlu destek sağlamak mümkün olsa da , Microsoft farklı bir yaklaşım seçti. GDI , farklı çıktı aygıtlarıyla çalışmak için " aygıt sürücüleri " adı verilen farklı kod parçalarını yükleyerek çalışır.

GDI'nin farklı aygıt sürücüleri yüklemesine izin veren aynı mimari konsept, Windows kabuğunun farklı Windows programlarını yüklemesine ve bu programların paylaşılan KULLANICI ve GDI kitaplıklarından API çağrıları başlatmasına izin verenle aynıdır . Bu kavram "dinamik bağlantı" idi.

Geleneksel bir paylaşılmayan statik kitaplıkta , yürütülebilir dosyası "bağlama" aşamasında oluşturulduğunda, kod bölümleri çağıran programa basitçe eklenir; iki program aynı rutini çağırırsa, rutin, ikisinin bağlantı aşamasında her iki programa da dahil edilir. Dinamik bağlantı ile paylaşılan kod, tek ve ayrı bir dosyaya yerleştirilir. Bu dosyayı çağıran programlar, bağlama işlemini gerçekleştiren işletim sistemiyle (veya Windows'un önceki sürümleri durumunda, işletim sistemi uzantısıyla) çalışma zamanında ona bağlanır.

Windows'un bu ilk sürümleri (1.0 - 3.11) için DLL'ler tüm GUI'nin temeliydi. Bu nedenle, görüntü sürücüleri yalnızca birleştirilmiş bir aygıt sürücüsü arabirimi (DDI) aracılığıyla aynı çizim API'sinin özel uygulamalarını sağlayan bir .DRV uzantısına sahip DLL'lerdi ve Çizim (GDI) ve GUI (KULLANICI) API'leri yalnızca dışa aktarılan işlev çağrılarıydı. GDI ve KULLANICI tarafından, .EXE uzantılı sistem DLL'leri.

İşletim sistemini dinamik olarak yüklenmiş kitaplıklardan oluşan bir koleksiyondan oluşturma fikri, Windows'un 2015'ten itibaren devam eden temel bir konseptidir. DLL'ler , modülerlik gibi paylaşılan kitaplıkların standart avantajlarını sağlar . Modülerlik, uygulamaların kendisinde herhangi bir değişiklik olmaksızın birkaç uygulama tarafından paylaşılan tek bir bağımsız DLL'de kod ve verilerde değişiklik yapılmasına izin verir.

Modülerliğin bir başka yararı, eklentiler için genel arabirimlerin kullanılmasıdır. Uygulamanın kendisinde herhangi bir değişiklik yapmadan eski ve yeni modüllerin çalışma zamanında önceden var olan uygulamalara sorunsuz bir şekilde entegre edilmesini sağlayan tek bir arayüz geliştirilebilir. Bu dinamik genişletilebilirlik kavramı , ActiveX'in temellerini oluşturan Bileşen Nesne Modeli ile en uç noktaya taşınmıştır .

Windows 1.x, 2.x ve 3.x'te tüm Windows uygulamaları aynı adres alanını ve aynı belleği paylaştı. Bir DLL, bu adres alanına yalnızca bir kez yüklendi; o andan itibaren, kitaplığı kullanan tüm programlar ona erişti. Kütüphanenin verileri tüm programlar arasında paylaşıldı. Bu, süreçler arası iletişimin dolaylı bir biçimi olarak kullanılabilir veya yanlışlıkla farklı programları bozabilir. Windows 95'te 32 bit kitaplıkların kullanıma sunulmasıyla birlikte, her işlem kendi adres alanında çalıştı. DLL kodu paylaşılabilirken, paylaşılan verilerin kitaplık tarafından açıkça istendiği durumlar dışında veriler özeldir. Bununla birlikte, Windows 95 , Windows 98 ve Windows Me'nin büyük bölümleri, başlatıldığında Pentium Pro mikroişlemcisinin performansını sınırlayan ve sonuçta Windows'un DOS tabanlı sürümlerinin kararlılığını ve ölçeklenebilirliğini sınırlayan 16 bit kitaplıklardan oluşturuldu .

DLL'ler Windows mimarisinin çekirdeğini oluştursalar da, topluca " DLL cehennemi " olarak adlandırılan çeşitli dezavantajları vardır . 2015 itibariyle Microsoft , DLL cehennemi sorunlarına bir çözüm olarak .NET Framework'ü tanıtıyor , ancak artık uygulamalar arasında üstün yalıtım sundukları için Microsoft Virtual PC ve Microsoft Application Virtualization gibi sanallaştırma tabanlı çözümleri destekliyorlar . DLL cehennemine alternatif bir azaltıcı çözüm, yan yana montaj uygulamak olmuştur .

Özellikleri

DLL'ler esasen EXE'ler ile aynı olduğundan, bağlantı sürecinin bir parçası olarak hangisinin üretileceği seçimi netlik içindir, çünkü her ikisinden de işlevleri ve verileri dışa aktarmak mümkündür.

Bir DLL dosyasını doğrudan yürütmek mümkün değildir, çünkü işletim sisteminin onu bir giriş noktasından yüklemesi için bir EXE'ye ihtiyaç duyar , dolayısıyla DLL'ler için giriş noktası ve minimum çerçeve sağlayan RUNDLL.EXE veya RUNDLL32.EXE gibi yardımcı programların varlığı söz konusudur. fazla destek olmadan yürütmek için yeterli işlevsellik içeren.

DLL'ler, paylaşılan kod ve veriler için bir mekanizma sağlayarak, paylaşılan kod/veri geliştiricisinin, uygulamaların yeniden bağlanmasına veya yeniden derlenmesine gerek kalmadan işlevselliği yükseltmesine olanak tanır. Uygulama geliştirme açısından Windows ve OS/2, işletim sisteminin bir sürümüne yönelik uygulamaların daha sonraki bir sürümde çalışmasına izin veren yükseltilmiş DLL'ler topluluğu olarak düşünülebilir. ve işlevsellik uyumludur.

DLL'ler, çağrı sürecinin bellek alanında ve aynı erişim izinleriyle yürütülür; bu, kullanımlarında çok az ek yük olduğu, ancak DLL'de herhangi bir hata varsa, çağrı yapan EXE için hiçbir koruma olmadığı anlamına gelir.

Hafıza yönetimi

In Windows API DLL dosyaları halinde düzenlenmiştir bölümler . Her bölümün yazılabilir veya salt okunur, yürütülebilir (kod için) veya yürütülemez (veri için) vb. gibi kendi öznitelikleri vardır.

DLL'deki kod, genellikle DLL'yi kullanan tüm işlemler arasında paylaşılır; yani fiziksel bellekte tek bir yer kaplarlar ve sayfa dosyasında yer kaplamazlar . Windows , DLL'leri için konumdan bağımsız kod kullanmaz ; bunun yerine kod , yüklenirken yeniden konumlandırmaya tabi tutulur ve DLL'yi yüklemek için ilk işlemin bellek alanında boş olan konumlardaki tüm giriş noktalarının adresleri sabitlenir. Çalışan tüm işlemlerin tek bir ortak adres alanını işgal ettiği eski Windows sürümlerinde, DLL kodunun tek bir kopyası tüm işlemler için her zaman yeterli olacaktır. Ancak, her program için ayrı adres alanları kullanan daha yeni Windows sürümlerinde, DLL'nin aynı yeniden konumlandırılmış kopyasını birden çok programda kullanmak, ancak her program DLL kodunu barındırmak için aynı sanal adreslere sahipse mümkündür. Bazı programlarda (veya önceden yüklenmiş DLL'lerin birleşimlerinde) bu adresler ücretsiz değilse, farklı bir yeniden konumlandırılmış giriş noktası kümesi kullanılarak DLL kodunun ek bir fiziksel kopyasının oluşturulması gerekecektir. Bir kod bölümü tarafından işgal edilen fiziksel bellek geri alınacaksa, içeriği atılır ve daha sonra gerektiğinde doğrudan DLL dosyasından yeniden yüklenir.

Kod bölümlerinin aksine, bir DLL dosyasının veri bölümleri genellikle özeldir; diğer bir deyişle, DLL'yi kullanan her işlem, tüm DLL verilerinin kendi kopyasına sahiptir. Opsiyonel olarak veri bölümleri paylaşımlı hale getirilerek bu paylaşımlı hafıza alanı üzerinden süreçler arası iletişime izin verilir . Ancak, paylaşılan DLL belleğinin kullanımı için kullanıcı kısıtlamaları geçerli olmadığından, bu bir güvenlik açığı oluşturur ; yani, bir işlem paylaşılan verileri bozabilir ve bu da diğer tüm paylaşım işlemlerinin istenmeyen şekilde davranmasına neden olabilir. Örneğin, bir konuk hesabı altında çalışan bir işlem, bu şekilde ayrıcalıklı bir hesap altında çalışan başka bir işlemi bozabilir. Bu, DLL'lerde paylaşılan bölümlerin kullanılmasından kaçınmak için önemli bir nedendir.

Bir DLL, belirli yürütülebilir paketleyiciler (örneğin UPX ) tarafından sıkıştırılırsa , kod bölümlerinin tümü okuma ve yazma olarak işaretlenir ve paylaşılmaz. Oku ve yaz kodu bölümleri, özel veri bölümlerine çok benzer, her işlem için özeldir. Bu nedenle, paylaşılan veri bölümlerine sahip DLL'ler, birden fazla program tarafından aynı anda kullanılması amaçlanıyorsa sıkıştırılmamalıdır, çünkü her program örneği, DLL'nin kendi kopyasını taşımak zorunda kalacak ve bu da artan bellek tüketimine neden olacaktır.

Kitaplıkları içe aktar

Statik kitaplıklar gibi, DLL'ler için içe aktarma kitaplıkları da .lib dosya uzantısıyla belirtilir. Örneğin, dosya oluşturma ve bellek yönetimi gibi Windows'un temel işlevleri için birincil dinamik kitaplık olan kernel32.dll , kernel32.lib aracılığıyla bağlanır. Uygun bir statik kitaplıktan bir içe aktarma kitaplığını söylemenin genel yolu boyuta göredir: içe aktarma kitaplığı, yalnızca bağlantı zamanında işlenecek gerçek DLL'ye atıfta bulunan semboller içerdiğinden çok daha küçüktür. Yine de her ikisi de Unix ar formatındaki dosyalardır.

Dinamik kitaplıklara bağlantı, genellikle yürütülebilir bir dosya oluşturmak için oluşturulurken veya bağlantı oluşturulurken bir içe aktarma kitaplığına bağlanarak gerçekleştirilir. Oluşturulan yürütülebilir dosya, daha sonra tüm DLL işlev çağrılarına başvurulan bir içe aktarma adres tablosu (IAT) içerir (başvurulan her DLL işlevi, IAT'de kendi girişini içerir). Çalışma zamanında, IAT, doğrudan ayrı olarak yüklenen DLL'deki bir işleve işaret eden uygun adreslerle doldurulur.

Cygwin/MSYS ve MinGW'de, içe aktarma kitaplıklarına geleneksel olarak .dll.a, hem Windows DLL son ekini hem de Unix ar son ekini birleştiren sonek verilir . Dosya biçimi benzerdir, ancak içe aktarmaları işaretlemek için kullanılan simgeler farklıdır (_head_foo_dll ve __IMPORT_DESCRIPTOR_foo). Onun rağmen GNU Binutils araç zinciri onlara ithalat kütüphaneleri ve bağlantı oluşturabilir, daha hızlı bağlantı doğrudan DLL etmektir. MinGW'de genlib adı verilen deneysel bir araç, MSVC tarzı sembollerle içe aktarma kitaplıkları oluşturmak için kullanılabilir.

Sembol çözünürlüğü ve bağlama

Bir DLL tarafından dışa aktarılan her işlev, sayısal bir sıra ve isteğe bağlı olarak bir adla tanımlanır. Benzer şekilde, işlevler bir DLL'den sıra veya ada göre içe aktarılabilir. Sıra, işlevin adres işaretçisinin DLL Verme Adresi tablosundaki konumunu temsil eder. Dahili işlevlerin yalnızca sıra ile dışa aktarılması yaygındır. Çoğu Windows API işlevi için farklı Windows sürümlerinde yalnızca adlar korunur; sıra sayıları değişebilir. Bu nedenle, Windows API işlevleri sıra sayılarına göre güvenilir bir şekilde içe aktarılamaz.

İşlevleri sıraya göre içe aktarmak, onları ada göre içe aktarmaktan yalnızca biraz daha iyi performans sağlar: DLL'lerin dışa aktarma tabloları ada göre sıralanır, bu nedenle bir işlevi bulmak için ikili arama kullanılabilir. Bulunan adın dizini daha sonra Sıralamayı Dışa Aktarma Sırası tablosunda aramak için kullanılır. 16-bit Windows'ta ad tablosu sıralanmadı, bu nedenle ad arama ek yükü çok daha belirgindi.

Da mümkündür bağlayan derleme zamanında ithal fonksiyonların adreslerini çözümlemek için, bir DLL, belirli bir sürümüne yürütülebilir. Ciltli ithalatı için bağlayıcı ithalat bağlı olduğu DLL damgası ve sağlama kaydeder. Çalışma zamanında Windows, kitaplığın aynı sürümünün kullanılıp kullanılmadığını denetler ve kullanılıyorsa, Windows içe aktarma işlemlerini atlar. Aksi takdirde, kitaplık bağlı olandan farklıysa, Windows içe aktarmaları normal bir şekilde işler.

Bağlı yürütülebilir dosyalar, derlendikleri ortamda çalıştırılırlarsa biraz daha hızlı ve farklı bir ortamda çalıştırılırlarsa tam olarak aynı zamanda yüklenirler, bu nedenle içe aktarmaları bağlamanın bir sakıncası yoktur. Örneğin, tüm standart Windows uygulamaları, ilgili Windows sürümlerinin sistem DLL'lerine bağlıdır. Bir uygulamanın içe aktarmalarını hedef ortamına bağlamak için iyi bir fırsat, uygulamanın yüklenmesi sırasındadır. Bu, kitaplıkları bir sonraki işletim sistemi güncellemesine kadar 'bağlı' tutar. Ancak, yürütülebilir dosyanın sağlama toplamını değiştirir, bu nedenle imzalı programlarla veya dosya sürümlerini yönetmek için sağlama toplamları ( MD5 sağlama toplamları gibi) kullanan bir yapılandırma yönetim aracı tarafından yönetilen programlarla yapılabilecek bir şey değildir . Daha yeni Windows sürümleri, yüklenen her kitaplık için sabit adreslere sahip olmaktan uzaklaştıkça (güvenlik nedenleriyle), bir yürütülebilir dosyayı bağlama fırsatı ve değeri azalmaktadır.

Açık çalışma zamanı bağlama

DLL dosyaları , (veya ) API işlevi kullanılarak Microsoft tarafından basitçe çalışma zamanı dinamik bağlantısı olarak adlandırılan bir işlem olan çalışma zamanında açıkça yüklenebilir . API fonksiyonu adıyla ihraç sembolleri aramak için kullanılır ve - DLL boşaltmak için. Bu işlevler benzerdir , ve de POSIX standart API. LoadLibraryLoadLibraryExGetProcAddressFreeLibrarydlopendlsymdlclose

Açık çalışma zamanı bağlama prosedürü, dil yapılarından ziyade Windows API'sine bağlı olduğundan , işlevlere yönelik işaretçileri destekleyen herhangi bir dilde aynıdır .

Gecikmeli yükleme

Normalde, DLL'nin içe aktarma kitaplığına bağlı bir uygulama, DLL bulunamazsa başlatılamaz, çünkü Windows, uygulamanın ihtiyaç duyabileceği tüm DLL'leri bulamadığı sürece uygulamayı çalıştırmayacaktır. Bununla birlikte, dinamik kitaplığın gecikmeli yüklenmesine izin vermek için bir uygulama bir içe aktarma kitaplığına bağlanabilir. Bu durumda, uygulama başladığında işletim sistemi DLL'yi bulmaya veya yüklemeye çalışmayacaktır; bunun yerine, işlevlerinden biri çağrıldığında, DLL'yi LoadLibrary ve GetProcAddress aracılığıyla bulmaya ve yüklemeye çalışacak olan bağlayıcı tarafından uygulamaya bir saplama eklenir. DLL bulunamazsa veya yüklenemezse ya da çağrılan işlev mevcut değilse, uygulama yakalanıp uygun şekilde işlenebilecek bir istisna oluşturur . Uygulama istisnayı işlemezse, işletim sistemi tarafından yakalanacak ve programı bir hata mesajı ile sonlandıracaktır.

Gecikmeli yükleme mekanizması ayrıca , DLL yüklendiğinde ve/veya herhangi bir DLL işlevi çağrıldığında uygulamanın ek işleme veya hata işleme gerçekleştirmesine olanak tanıyan bildirim kancaları sağlar .

Derleyici ve dil konuları

Delfi

Bir kaynak dosyada, libraryyerine anahtar sözcük kullanılır program. Dosyanın sonunda, dışa aktarılacak işlevler exportsyan tümcede listelenir .

Delphi , LIBDLL'lerden işlevleri içe aktarmak için dosyalara ihtiyaç duymaz ; Bir DLL'ye bağlanmak için, externalanahtar sözcük, işlev bildiriminde DLL adını namebelirtmek ve ardından sembolü (farklıysa) adlandırmak veya indexdizini tanımlamak için kullanılır.

Microsoft Visual Basic

Gelen Visual Basic (VB), sadece çalışma zamanı bağlama desteklenir; ancak LoadLibraryve GetProcAddressAPI işlevlerinin kullanımına ek olarak , içe aktarılan işlevlerin bildirimlerine izin verilir.

DLL işlevlerini bildirimler yoluyla içe aktarırken, DLLdosya bulunamazsa VB bir çalışma zamanı hatası oluşturur . Geliştirici hatayı yakalayabilir ve uygun şekilde işleyebilir.

VB'de DLL'ler oluştururken, IDE yalnızca ActiveX DLL'lerinin oluşturulmasına izin verir, ancak kullanıcının bağlayıcıya dışa aktarılan her işlevin sıra konumunu ve adını tanımlayan bir .DEF dosyası eklemesini açıkça söylemesine izin vermek için yöntemler oluşturulmuştur. Bu, kullanıcının Visual Basic (Sürüm 6 veya altı) kullanarak bir "Declare" deyimi aracılığıyla başvurulabilecek standart bir Windows DLL dosyası oluşturmasına olanak tanır.

C ve C++

Microsoft Visual C++ (MSVC), işlevlerin doğrudan C++ kodunda içe veya dışa aktarılmış olarak belirtilmesine izin veren standart C++'a çeşitli uzantılar sağlar ; bunlar , GCC'nin Windows sürümleri de dahil olmak üzere diğer Windows C ve C++ derleyicileri tarafından benimsenmiştir . Bu uzantılar, bir işlev bildiriminden önce özniteliği kullanır . C++'dan C işlevlerine erişildiğinde , derleyiciye C bağlantısının kullanılması gerektiğini bildirmek için C++ kodunda olduğu gibi bildirilmeleri gerektiğini unutmayın. __declspecextern "C"

__declspecÖznitelikleri kullanarak içe aktarılan veya dışa aktarılan işlevleri belirtmenin yanı sıra DEF, proje tarafından kullanılan dosyanın IMPORT veya EXPORTS bölümünde listelenebilirler . DEFDosya yerine derleyici daha bağlayıcı ile işlenir, ve bu şekilde bu C ++ özgü değildir.

DLL derleme hem üretecek DLLve LIBdosyaları. LIBDosya (ithalat kütüphanesi) derleme sırasında bir DLL karşı bağlantısına kullanılır; çalışma zamanı bağlantısı için gerekli değildir. DLL bir Bileşen Nesne Modeli (COM) sunucusu değilse, DLLdosya PATH ortam değişkeninde listelenen dizinlerden birine, varsayılan sistem dizinine veya onu kullanan programla aynı dizine yerleştirilmelidir. COM sunucusu DLL'leri, DLL'nin konumunu ve global olarak benzersiz kimliğini ( GUID ) kayıt defterine yerleştiren regsvr32.exe kullanılarak kaydedilir . Programlar daha sonra konumunu bulmak için kayıt defterinde GUID'sini arayarak DLL'yi kullanabilir veya sınıf tanımlayıcısını ve arabirim tanımlayıcısını kullanarak dolaylı olarak COM nesnesinin bir örneğini oluşturabilir.

Programlama örnekleri

DLL içe aktarmalarını kullanma

Aşağıdaki örnekler, derleme zamanında bir DLL'ye bağlanmak için sembolleri içe aktarmak için dile özgü bağlamaların nasıl kullanılacağını gösterir.

Delfi

{$APPTYPE CONSOLE}

program Example;

// import function that adds two numbers
function AddNumbers(a, b : Double): Double; StdCall; external 'Example.dll';

// main program
var
   R: Double;

begin
  R := AddNumbers(1, 2);
  Writeln('The result was: ', R);
end.

C

Statik bağlamadan önce Example.lib dosyası projeye dahil edilmelidir (Örnek.dll'nin oluşturulduğu varsayılarak) (Proje için Mevcut Öğeyi Ekle seçeneği!). Örnek.lib dosyası, DLL derlenirken derleyici tarafından otomatik olarak oluşturulur. Bağlayıcı, AddNumbers'ın tanımını nerede bulacağını bilemeyeceğinden , yukarıdaki ifadeyi yürütmemek bağlama hatasına neden olur . DLL Example.dll dosyasının, .exe dosyasının aşağıdaki kod tarafından oluşturulacağı konuma da kopyalanması gerekebilir.

#include <windows.h>
#include <stdio.h>

// Import function that adds two numbers
extern "C" __declspec(dllimport) double AddNumbers(double a, double b);

int main(int argc, char *argv[])
{
    double result = AddNumbers(1, 2);
    printf("The result was: %f\n", result);
    return 0;
}

Açık çalışma zamanı bağlantısını kullanma

Aşağıdaki örnekler, dile özgü Windows API bağlamalarını kullanarak çalışma zamanı yükleme ve bağlama olanaklarının nasıl kullanılacağını gösterir.

Örnek.dll'nin yazar tarafından istenmeyen bir yere (geçerli çalışma dizini sistem kitaplığı konumlarından önce gider ) ve dolayısıyla kitaplığın kötü amaçlı bir sürümüne çözümlenebileceğinden , dört örneğin tümünün DLL önyükleme saldırılarına karşı savunmasız olduğunu unutmayın . Microsoft'un güvenli kitaplık yüklemeyle ilgili kılavuzu için başvuruya bakın: herhangi bir kitaplık yüklenmeden önce geçerli dizin aramasını kaldırmak için SetDllDirectoryWin kullanılmalıdır kernel32.

Microsoft Visual Basic

Option Explicit
Declare Function AddNumbers Lib "Example.dll" _
(ByVal a As Double, ByVal b As Double) As Double

Sub Main()
	Dim Result As Double
	Result = AddNumbers(1, 2)
	Debug.Print "The result was: " & Result
End Sub

Delfi

program Example;
  {$APPTYPE CONSOLE}
  uses Windows;
  var
  AddNumbers:function (a, b: integer): Double; StdCall;
  LibHandle:HMODULE;
begin
  LibHandle := LoadLibrary('example.dll');
  if LibHandle <> 0 then
    AddNumbers := GetProcAddress(LibHandle, 'AddNumbers');
  if Assigned(AddNumbers) then
    Writeln( '1 + 2 = ', AddNumbers( 1, 2 ) );
  Readln;
end.

C

#include <windows.h>
#include <stdio.h>

// DLL function signature
typedef double (*importFunction)(double, double);

int main(int argc, char **argv)
{
	importFunction addNumbers;
	double result;
	HINSTANCE hinstLib;

	// Load DLL file
	hinstLib = LoadLibrary(TEXT("Example.dll"));
	if (hinstLib == NULL) {
		printf("ERROR: unable to load DLL\n");
		return 1;
	}

	// Get function pointer
	addNumbers = (importFunction) GetProcAddress(hinstLib, "AddNumbers");
	if (addNumbers == NULL) {
		printf("ERROR: unable to find DLL function\n");
		FreeLibrary(hinstLib);
		return 1;
	}

	// Call function.
	result = addNumbers(1, 3);

	// Unload DLL file
	FreeLibrary(hinstLib);

	// Display result
	printf("The result was: %f\n", result);

	return 0;
}

piton

Python ctypes bağlaması, POSIX sistemlerinde POSIX API'sini kullanır.

import ctypes

my_dll = ctypes.cdll.LoadLibrary("Example.dll")

# The following "restype" method specification is needed to make
# Python understand what type is returned by the function.
my_dll.AddNumbers.restype = ctypes.c_double

p = my_dll.AddNumbers(ctypes.c_double(1.0), ctypes.c_double(2.0))

print("The result was:", p)

Bileşen Nesne Modeli

Bileşen Nesne Modeli (COM) uygulanmasını barındırmak için ikili standartlar ortaya nesneler DLL ve EXE dosyaları. Arayüzün dilden bağımsız ve makine tarafından okunabilir bir açıklamasının yanı sıra bu dosyaları bulmak ve sürümlendirmek için mekanizmalar sağlar. COM nesnelerini bir DLL'de barındırmak daha hafiftir ve kaynakları istemci işlemiyle paylaşmalarına olanak tanır. Bu, COM nesnelerinin Visual Basic ve ASP gibi basit GUI ön uçlarına güçlü arka uçlar uygulamasını sağlar. Ayrıca betik dillerinden programlanabilirler.

DLL ele geçirme

Genellikle DLL ele geçirme, DLL sahtekarlığı, DLL ön yükleme veya ikili yerleştirme olarak bilinen bir güvenlik açığı nedeniyle , birçok program, bu programlar tarafından açılan bir veri dosyasıyla aynı klasörde bulunan kötü amaçlı bir DLL dosyasını yükleyecek ve yürütecektir. Güvenlik açığı, 2000 yılında Georgi Guninski tarafından keşfedildi. Ağustos 2010'da, ACROS Security'nin onu yeniden keşfetmesinden ve yüzlerce programın savunmasız bulunmasından sonra dünya çapında tanınırlık kazandı. Güvenli olmayan konumlardan, yani İndirilenler veya Temp dizini gibi kullanıcı tarafından yazılabilen klasörlerden çalıştırılan programlar , hemen hemen her zaman bu güvenlik açığından etkilenir.

Ayrıca bakınız

Referanslar

  • Hart, Johnson. Windows Sistem Programlama Üçüncü Sürüm . Addison-Wesley, 2005. ISBN  0-321-25619-0 .
  • Rektör, Brent ve ark. Win32 Programlama . Addison-Wesley Developers Press, 1997. ISBN  0-201-63492-9 .

Dış bağlantılar