Bir DLL'de ne var ve nasıl çalışıyor?


87

C # kodumda her zaman DLL'leri referans alıyorum, ancak açıklığa kavuşturmak istediğim bir şekilde bir gizem olarak kaldılar. Bu, DLL'lerle ilgili soruların bir tür beyin dökümüdür.

Bir DLL'nin dinamik olarak bağlantılı bir kitaplık olduğunu anlıyorum, bu da başka bir programın "işlevsellik" elde etmek için bu kitaplığa çalışma zamanında erişebileceği anlamına geliyor. Ancak, aşağıdaki ASP.NET projesini Web.dllve Business.dll( Web.dllön uç işlevselliği ve Business.dlltürler ve yöntemler için başvurular ) ile düşünün .

  1. Web.dllDinamik olarak hangi noktada bağlanır Business.dll? Windows HDD'de Word (vb.) Kullanırken görünüşte küçük görevler için çok fazla şey fark ediyorsunuz ve Word'ün kapandığını ve diğer DLL'lerden işlevsellik açısından dinamik olarak bağlantı kurduğunu tahmin ediyorum?

    1 A. Ek olarak, DLL'yi yükleyen ve bağlayan şey - işletim sistemi veya .NET çerçevesi gibi bazı çalışma zamanı çerçevesi?

    1b. "Bağlama" süreci nedir? Uyumluluk kontrolleri yapıldı mı? Aynı belleğe mi yükleniyor? Bağlama aslında ne anlama geliyor?

  2. DLL'deki kodu gerçekte ne çalıştırır? İşlemci tarafından çalıştırılıyor mu veya işlemci DLL içindeki kodu anlamadan önce başka bir çeviri veya derleme aşaması var mı?

    2a. C # .NET'te yerleşik bir DLL olması durumunda, bunu çalıştıran nedir: .NET çerçevesi mi yoksa işletim sistemi mi?

  3. Linux'tan bir DLL bir Windows sisteminde çalışıyor mu (böyle bir şey varsa) veya işletim sistemine özel mi?

  4. DLL'ler belirli bir çerçeveye özel mi? C # .NET kullanılarak oluşturulan bir DLL, örneğin Borland C ++ ile oluşturulmuş bir DLL tarafından kullanılabilir mi?

    4a. 4'ün yanıtı "hayır" ise, o zaman DLL'nin anlamı nedir? Neden çeşitli çerçeveler bağlantılı dosyalar için kendi formatlarını kullanmıyor? Örneğin: .NET'te yerleşik bir .exe, .abc dosya türünün koduna bağlanabileceği bir şey olduğunu bilir.

  5. İçin geri gidiş Web.dll/ Business.dllörnek - Ben referansa ihtiyaç müşteri bir sınıf türü almak için Business.dllgelen Web.dll. Bu, Business.dllmüşteri sınıfının gerçekte ne olduğuna dair bir tür spesifikasyon içerdiği anlamına gelmelidir . Dosyamı Business.dllDelphi'de derlemiş olsaydım : C # onu anlayıp bir müşteri sınıfı oluşturabilir miydi, yoksa bir tür başlık bilgisi veya "hey üzgünüm beni sadece başka bir Delphi DLL'den kullanabilirsiniz" diyen bir şey var mı? ?

    5a. Aynı yöntem yöntemler için de geçerlidir; CreateInvoice()Bir DLL'ye bir yöntem yazıp , bunu C ++ 'da derleyip sonra ona C # erişip çalıştırabilir miyim? Bunu yapmama engel olan veya bunu yapmama izin veren nedir?

  6. DLL korsanlığı konusunda, kesinlikle değiştirilen (kötü) DLL, ele geçirilenle aynı yöntem imzalarını ve türlerini içermelidir. Orijinal DLL'de hangi yöntemlerin mevcut olduğunu bulabilirseniz, bunu yapmak zor olmazdı.

    6a. C # programımda başka bir DLL'ye erişip erişemeyeceğime karar veren nedir? Ele geçirilen DLL'm orijinaliyle tamamen aynı yöntemleri ve türleri içeriyorsa, ancak başka bir dilde derlenmişse, çalışır mı?

DLL içe aktarma ve DLL kaydı nedir?


21
Bu soru, SO tarihindeki en uzun cevabı soruyor olabilir.
Matti Virkkunen

4
12 ayrı Soru olmalıydı.
Henk Holterman

2
Bu harika bir soru, ancak @Chaos ve @Matti'ye gerçekten katılıyorum. Bu soru daha fazla odaklanmaya ihtiyaç duyar ve birkaç farklı soruya bölünebilir / bölünmelidir.
Chris Thompson


1
Şimdiye kadar bir topluluk wiki olmalı.
leppie

Yanıtlar:


74

Her şeyden önce, çok farklı iki DLL türü arasındaki farkı anlamanız gerekir. Microsoft, hem .NET (yönetilen kod) hem de yerel kod ile aynı dosya uzantılarını (.exe ve .dll) kullanmaya karar verdi, ancak yönetilen kod DLL'leri ve yerel DLL'ler çok farklı.

1) web.dll, business.dll'ye dinamik olarak hangi noktada bağlanır? Windows HDD'de Word vb. Kullanırken görünüşte küçük görevler için çok fazla şey fark ettiniz ve bu Word'ün diğer DLL'lerden işlevsellik açısından dinamik olarak bağlandığını tahmin ediyorum.

1) .NET durumunda, DLL'ler genellikle DLL'den herhangi bir şeye erişmeye çalışan ilk yöntem çalıştırıldığında isteğe bağlı olarak yüklenir. Bu nedenle, bir DLL yüklenemiyorsa, kodunuzun herhangi bir yerinde TypeNotFoundExceptions alabilirsiniz. Word gibi bir şey aniden HDD'ye çok fazla erişmeye başladığında, muhtemelen değişiyor (RAM'de yer açmak için diske takas edilen verileri alıyor)

1a) Ek olarak, DLL'yi yükleyen ve bağlayan şey - İşletim Sistemi veya .Net çerçevesi gibi bazı çalışma zamanı çerçevesi?

1a) Yönetilen DLL'ler durumunda, .NET çerçevesi yüklenir, JIT derler (.NET bayt kodunu yerel koda derler) ve DLL'leri birbirine bağlar. Yerel DLL'ler söz konusu olduğunda, DLL'yi yükleyen ve birbirine bağlayan işletim sisteminin bir bileşenidir (yerel DLL'ler zaten yerel kod içerdiğinden derleme gerekmez).

1b) "Bağlama" süreci nedir? Uyumluluğun olup olmadığı kontrol ediliyor mu? Aynı belleğe mi yükleniyor? Bağlama aslında ne anlama geliyor?

1b) Bağlantı, DLL'deki sembollere (örneğin yöntemler) çağıran koddaki referansların (örneğin yöntem çağrıları) DLL'deki şeylerin gerçek adresleriyle değiştirilmesidir. Bu gereklidir, çünkü DLL'deki şeylerin nihai adresleri belleğe yüklenmeden önce bilinemez.

2) DLL'deki kodu gerçekte ne çalıştırır? İşlemci tarafından çalıştırılıyor mu veya işlemci DLL içindeki kodu anlamadan önce başka bir çeviri veya derleme aşaması var mı?

2) Windows'ta .exe dosyaları ve .dll dosyaları tamamen aynıdır. Yerel .exe ve .dll dosyaları yerel kod içerir (işlemcinin yürüttüğü şeyler), bu nedenle çevirmeye gerek yoktur. Yönetilen .exe ve .dll dosyaları, ilk olarak JIT tarafından derlenen (yerel koda çevrilen) .NET bayt kodunu içerir.

2a) C # .net'ten oluşturulmuş bir DLL durumunda bunu çalıştıran nedir? .Net çerçevesi mi yoksa işletim sistemi mi?

2a) Kod JIT derlendikten sonra, herhangi bir kodla aynı şekilde çalıştırılır.

3) Linux'tan bir DLL bir Windows sisteminde çalışıyor mu (böyle bir şey varsa) veya işletim sistemine özel mi?

3) Yönetilen DLL'ler, her iki platformdaki çerçeveler güncel olduğu ve DLL'yi yazan kişi yerel çağrıları kullanarak uyumluluğu kasten bozmadığı sürece olduğu gibi çalışabilir. Biçimler farklı olduğu için yerel DLL'ler olduğu gibi çalışmayacaktır (her ikisi de aynı işlemci platformu için ise, içindeki makine kodu aynı olsa bile). Bu arada, Linux'ta "DLL'ler" .so (paylaşılan nesne) dosyaları olarak bilinir.

4) Belirli bir çerçeveye özel mi? C # .Net kullanılarak oluşturulan bir DLL Borland C ++ ile oluşturulmuş bir DLL tarafından kullanılabilir mi (yalnızca örnek)?

4) Yönetilen DLL'ler .NET çerçevesine özeldir, ancak doğal olarak uyumlu herhangi bir dille çalışırlar. Yerel DLL'ler, herkes aynı kuralları kullandığı sürece uyumludur (çağrı kuralları (işlev bağımsız değişkenleri makine kodu düzeyinde nasıl iletilir), sembol adlandırma vb.)

5) web.dll / business.dll örneğine dönüyoruz. Sınıf tipi müşteri almak için web.dll'den business.dll'ye başvurmam gerekir. Bu, business.dll'nin bir müşteri sınıfının gerçekte ne olduğuna dair bir tür belirtim içerdiği anlamına gelmelidir. Business.dll dosyamı Delphi'nin C # anlayacağını ve bir müşteri sınıfı oluşturabileceğini söyleyerek derlemiş olsaydım - veya bir tür başlık bilgisi veya "hey üzgünüm beni yalnızca başka bir delphi dll'den kullanabilirsiniz" diyen bir şey var mı? .

5) Yönetilen DLL'ler, içerdikleri her sınıfın, yöntemin, alanın vb. Tam açıklamasını içerir. AFAIK Delphi, .NET'i desteklemez, bu nedenle .NET'te doğrudan kullanılamayan yerel DLL'ler oluşturur. Muhtemelen PInvoke ile fonksiyonları çağırabileceksiniz, ancak sınıf tanımları bulunmayacaktır. Delphi kullanmıyorum, bu yüzden tür bilgilerini DLL'lerle nasıl sakladığını bilmiyorum. Örneğin C ++, tür bildirimlerini içeren ve DLL ile dağıtılması gereken başlık (.h) dosyalarına dayanır.

6) DLL korsanlığı konusunda, kesinlikle ikame (kötü) DLL, ele geçirilenin türü gibi tam yöntem imzalarını içermelidir. Orijinal DLL'de hangi yöntemlerin vb. Bulunduğunu öğrenirseniz, bunu yapmak zor olmazdı.

6) Gerçekten de, DLL'yi kolayca değiştirebiliyorsanız bunu yapmak zor değildir. Bunu önlemek için kod imzalama kullanılabilir. Birinin imzalı bir DLL'yi değiştirmesi için gizli tuttuğu imzalama anahtarını bilmesi gerekir.

6a) Burada biraz tekrarlanan bir soru var ama bu, C # programımın başka bir DLL'ye erişip erişemeyeceğime karar verdiğine geri dönüyor? Ele geçirilen DLL'm orijinaliyle tamamen aynı yöntemleri ve türleri içeriyorsa, ancak başka bir dilde derlenmiş olsaydı işe yarar mıydı?

6a) Herhangi bir .NET diliyle yapılmış, yönetilen bir DLL olduğu sürece çalışır.

  • DLL içe aktarma nedir? ve dll kaydı?

"DLL içe aktarma" birçok anlama gelebilir, genellikle bir DLL dosyasına başvurmak ve içindeki şeyleri kullanmak anlamına gelir.

DLL kaydı, Windows'ta DLL dosyalarını sistemdeki herhangi bir yazılımın kullanımına sunmak için COM bileşenleri olarak küresel olarak kaydetmek için yapılan bir işlemdir.


3
# 4'e, .NET'in DLL'leri COM (Ortak Nesne Modeli) anlayan / kullanan herhangi bir yerel programla uyumlu olacak şekilde çevirebileceğini ekleyeceğim. Çok güzel cevaplar tho.
MerickOWA

7

Bir .dll dosyası, uygulamanızda kullanabileceğiniz derlenmiş kodu içerir.

Bazen .dll'yi derlemek için kullanılan araç, bazen önemli değil. Projenizde .dll'ye başvurabilirseniz, .dll'nin açığa çıkan işlevlerini kodlamak için hangi aracın kullanıldığı önemli değildir.

Bağlama, derleme zamanında bağlanan sınıflarınız gibi statik olarak bağlı kitaplıkların aksine çalışma zamanında gerçekleşir.

.Dll'yi, uygulamanızın ihtiyaç duyduğu ve kendiniz yazmak istemediğiniz bir şeyi sağlayan bir kara kutu olarak düşünebilirsiniz. Evet, .dll imzasını anlayan biri, içinde farklı kod bulunan başka bir .dll dosyası oluşturabilir ve arayan uygulamanız farkı anlayamaz.

HTH


6

1) web.dll, business.dll'ye dinamik olarak hangi noktada bağlanır? Windows HDD'de Word vb. Kullanırken görünüşte küçük görevler için çok fazla şey fark ettiniz ve bu Word'ün diğer DLL'lerden işlevsellik açısından dinamik olarak bağlandığını tahmin ediyorum.

1) Yükleme ile bağlantı kurmayı karıştırdığınızı düşünüyorum. Bağlantı, istenen şeyin mevcut olduğundan emin olmak için tüm kontrollerin ve dengelerin test edildiği zamandır. Yükleme anında dll'nin bazı bölümleri belleğe yüklenir veya disk belleği dosyasına aktarılır. Bu, gördüğünüz HD aktivitesidir.

Dinamik bağlantı, statik bağlamadan farklıdır, çünkü statik bağlamada, tüm nesne kodu bağlantı anında ana .exe'ye yerleştirilir. Dinamik bağlantı ile, nesne kodu ayrı bir dosyaya (dll) yerleştirilir ve .exe'den farklı bir zamanda yüklenir.

Dinamik bağlantı örtük (yani uygulama bir içe aktarma kitaplığıyla bağlantı kurar) veya açık olabilir (yani uygulama dll'yi yüklemek için LoadLibrary'yi (ex) kullanır).

Örtük durumda, / DELAYLOAD, uygulama gerçekten ihtiyaç duyana kadar dll'nin yüklenmesini ertelemek için kullanılabilir. Aksi takdirde, işlemin başlatılmasının bir parçası olarak en azından bazı bölümleri yüklenir (işlem adres alanına eşlenir). Ayrıca dll, işlem aktifken asla boşaltılmamasını isteyebilir.

COM, COM dll'lerini yüklemek için LoadLibrary kullanır. Örtük durumda bile, sistemin işlem başlangıcında veya ilk kullanımda dll'yi yüklemek için LoadLibrary'ye benzer bir şey kullandığını unutmayın.

2) DLL'deki kodu gerçekte ne çalıştırır? İşlemci tarafından çalıştırılıyor mu veya işlemci DLL içindeki kodu anlamadan önce başka bir çeviri veya derleme aşaması var mı?

2) Dll'ler, tıpkı .exes gibi nesne kodu içerir. Dll dosyasının biçimi neredeyse bir exe dosyasının biçimiyle aynıdır. İki dosyanın başlıklarında farklı olan yalnızca bir bit olduğunu duydum.

C # .net'ten oluşturulmuş bir DLL olması durumunda, .Net çerçevesi onu çalıştırır.

3) Linux'tan bir DLL bir Windows sisteminde çalışıyor mu (böyle bir şey varsa) veya işletim sistemine özel mi?

3) DLL'ler platforma özeldir.

4) Belirli bir çerçeveye özel mi? C # .Net kullanılarak oluşturulan bir DLL Borland C ++ ile oluşturulmuş bir DLL tarafından kullanılabilir mi (yalnızca örnek)?

4) Dll'ler, özel bir özen gösterilmesi veya ek tutkal kodu yazılması durumunda diğer çerçevelerle birlikte çalışabilir.

Dll'ler, bir şirket örtüşen yeteneklere sahip birden fazla ürün sattığında çok kullanışlıdır. Örneğin, şirkette 30'dan fazla farklı ürün tarafından kullanılan bir raster i / o dll bulunduruyorum. Birden fazla ürün kuruluysa, dll'nin bir yükseltmesi tüm ürünleri yeni tarama biçimlerine yükseltebilir.

5) web.dll / business.dll örneğine dönüyoruz. Sınıf tipi müşteri almak için web.dll'den business.dll'ye başvurmam gerekir. Bu, business.dll'nin bir müşteri sınıfının gerçekte ne olduğuna dair bir tür belirtim içerdiği anlamına gelmelidir. Business.dll dosyamı Delphi'nin C # anlayacağını ve bir müşteri sınıfı oluşturabileceğini söyleyerek derlemiş olsaydım - veya bir tür başlık bilgisi veya "hey üzgünüm beni yalnızca başka bir delphi dll'den kullanabilirsiniz" diyen bir şey var mı? .

5) Platforma bağlı olarak, bir dll'nin yetenekleri .h dosyaları, .tlb dosyaları veya .net üzerindeki diğer yollarla çeşitli şekillerde sunulur.

6) DLL korsanlığı konusunda, kesinlikle ikame (kötü) DLL, ele geçirilenin türü gibi tam yöntem imzalarını içermelidir. Orijinal DLL'de hangi yöntemlerin vb. Bulunduğunu öğrenirseniz, bunu yapmak zor olmazdı.

6) dumpbin / export ve dumbin / import, .exe ve .dll'lerde kullanılacak ilginç araçlardır.


3) DLL platforma özeldir
Henk Holterman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.