Pliki DLL i LIB - co i dlaczego?

214

Niewiele wiem o bibliotekach DLL i LIB, poza tym, że zawierają one niezbędny kod wymagany do poprawnego działania programu - bibliotek. Ale dlaczego kompilatory je generują? Czy nie byłoby łatwiej po prostu zawrzeć cały kod w jednym pliku wykonywalnym? Jaka jest różnica między bibliotekami DLL a bibliotekami LIB?

Xonara
źródło

Odpowiedzi:

298

Istnieją biblioteki statyczne (LIB) i biblioteki dynamiczne (DLL) - należy jednak pamiętać, że pliki .LIB mogą być bibliotekami statycznymi (zawierającymi pliki obiektowe) lub bibliotekami importowymi (zawierającymi symbole umożliwiające linkerowi połączenie z biblioteką DLL).

Biblioteki są używane, ponieważ możesz mieć kod, którego chcesz używać w wielu programach. Na przykład, jeśli napiszesz funkcję, która liczy liczbę znaków w ciągu, funkcja ta będzie przydatna w wielu programach. Po uzyskaniu prawidłowego działania tej funkcji nie trzeba ponownie kompilować kodu za każdym razem, gdy go używasz, więc umieść kod wykonywalny dla tej funkcji w bibliotece, a linker może wyodrębnić i wstawić skompilowany kod do programu . Z tego powodu biblioteki statyczne są czasami nazywane „archiwami”.

Biblioteki dynamiczne posuwają się o krok dalej. Wydaje się niepotrzebne, aby wiele kopii funkcji biblioteki zajmowało miejsce w każdym z programów. Dlaczego nie wszyscy mogą udostępniać jedną kopię funkcji? Po to są biblioteki dynamiczne. Zamiast kompilować kod biblioteki w programie podczas kompilacji, można go uruchomić, mapując go do programu podczas ładowania do pamięci. Wiele programów działających jednocześnie z tymi samymi funkcjami może współużytkować jedną kopię, oszczędzając pamięć. W rzeczywistości biblioteki dynamiczne można ładować tylko w razie potrzeby, w zależności od ścieżki w kodzie. Nie ma sensu zajmować pamięci przez procedury drukarki, jeśli nie drukujesz. Z drugiej strony oznacza to, że musisz mieć kopię biblioteki dynamicznej zainstalowaną na każdym komputerze, na którym działa Twój program.

Na przykład prawie każdy program napisany w „C” będzie potrzebował funkcji z biblioteki zwanej „biblioteką wykonawczą C”, chociaż niewiele programów będzie potrzebowało wszystkich funkcji. Środowisko wykonawcze C jest dostępne zarówno w wersji statycznej, jak i dynamicznej, dzięki czemu można określić, z której wersji korzysta program w zależności od konkretnych potrzeb.

Charles E. Grant
źródło
81
Okazuje się, że .LIBplikami mogą być biblioteki statyczne (zawierające pliki obiektowe) lub biblioteki importu (zawierające symbole umożliwiające linkerowi połączenie z biblioteką DLL). Zastanawiam się, dlaczego tak jest.
Lumi
2
dobre wytłumaczenie! Kod jest współdzielony, a dane (domyślnie) nie są dzielone między aplikacjami korzystającymi z biblioteki DLL.
mox
4
@Lumi: Dobra uwaga. Jeśli chodzi o biblioteki DLL, mamy dwa rodzaje łączenia. Niejawne łączenie , gdy mamy .libplik dostarczony przez twórcę DLL wraz z odpowiednimi nagłówkami; to .libjest po prostu deskryptor DLL docelowej, zawiera adresy, punkt wejścia, itd., ale żaden kod. To .libmusi być przekazywane na łącznik. Drugi to bezpośrednie połączenie, gdy korzystamy z biblioteki DLL, ręcznie ładując ją z LoadLibraryfunkcją. W tym typie nie potrzebujemy tego .libpliku, ale musimy włożyć trochę wysiłku, aby znaleźć eksport DLL, ich adresy i wywołać te funkcje za pomocą wskaźników.
itachi,
37

Kolejnym aspektem jest bezpieczeństwo (zaciemnianie). Po wyodrębnieniu fragmentu kodu z głównej aplikacji i umieszczeniu go w „oddzielnej” bibliotece Dynamic-Link łatwiej jest zaatakować, przeanalizować (poddać inżynierii wstecznej) kod, ponieważ został on wyizolowany. Gdy ten sam fragment kodu jest przechowywany w bibliotece LIB, jest on częścią skompilowanej (połączonej) aplikacji docelowej, a zatem trudniej jest wydzielić (odróżnić) ten fragment kodu od reszty docelowych plików binarnych.

mox
źródło
Aspekt bezpieczeństwa był dla mnie nowy. Czy powyższe rozumowanie jest prawdziwe w przypadku aplikacji C # wywołującej natywną niezarządzaną bibliotekę DLL C ++?
Martin
1
Ale LIB też jest izolowany, prawda? Dlatego atakujący może po prostu przeanalizować LIB. Czy może jest to powszechny scenariusz, że LIB nie jest publicznie dostępny?
Nick Russler
8
LIB jest również „izolowany”, jeśli chodzi o proces kompilatora, ale kiedy konsolidator po złożeniu części razem, LIB jest częścią EXE i nie można go odróżnić od własnego kodu.
mox
17

Jednym z ważnych powodów tworzenia DLL / LIB zamiast kompilowania kodu w pliku wykonywalnym jest ponowne użycie i przeniesienie. Przeciętna aplikacja Java lub .NET (na przykład) najprawdopodobniej użyje kilku bibliotek stron trzecich (lub frameworka). O wiele łatwiej i szybciej jest po prostu kompilować w oparciu o gotową bibliotekę, zamiast kompilować cały kod innej firmy do aplikacji. Kompilowanie kodu w bibliotekach zachęca również do dobrych praktyk projektowania, np. Projektowania klas do wykorzystania w różnych typach aplikacji.

Andy White
źródło
7

DLL to biblioteka funkcji współdzielonych przez inne programy wykonywalne. Wystarczy zajrzeć do katalogu windows / system32, a znajdziesz ich kilkadziesiąt. Gdy program tworzy bibliotekę DLL, zwykle tworzy również plik lib, aby program * .exe mógł rozpoznać symbole zadeklarowane w bibliotece DLL.

.Lib to biblioteka funkcji, które są statycznie powiązane z programem - NIE są one współużytkowane przez inne programy. Każdy program, który łączy się z plikiem * .lib, zawiera cały kod w tym pliku. Jeśli masz dwa programy A.exe i B.exe, które łączą się z C.lib, oba A i B będą zawierać kod w C.lib.

Sposób tworzenia bibliotek DLL i bibliotek lib zależy od używanego kompilatora. Każdy kompilator robi to inaczej.

Vinodhini Ramasamy
źródło
4

Kolejna różnica polega na wydajności.

Ponieważ biblioteka DLL jest ładowana w czasie wykonywania przez pliki .exe, pliki .exe i DLL działają z koncepcją pamięci współużytkowanej, a zatem wydajność jest niska w stosunku do łączenia statycznego.

Z drugiej strony .lib to kod, który jest statycznie powiązany w czasie kompilacji z każdym żądanym procesem. Dlatego pliki .exe będą miały pojedynczą pamięć, zwiększając w ten sposób wydajność procesu.

Girish Reddyvari
źródło