Różnica między bibliotekami statycznymi i współdzielonymi?

560

Jaka jest różnica między bibliotekami statycznymi i współdzielonymi?

Używam Eclipse i istnieje kilka typów projektów, w tym biblioteki statyczne i biblioteki współdzielone? Czy jedna ma przewagę nad drugą?

Mohit Deshpande
źródło
4
Wikipedia ma dobry opis rozróżnienia między bibliotekami statycznymi, dynamicznymi i współdzielonymi.
Adam Holmberg,

Odpowiedzi:

745

Biblioteki współdzielone to pliki .so (lub w .dll systemu Windows lub w .dylib systemu OS X). Cały kod związany z biblioteką znajduje się w tym pliku, a programy używają go w czasie wykonywania. Program korzystający z biblioteki współużytkowanej odnosi się tylko do kodu używanego w bibliotece współużytkowanej.

Biblioteki statyczne to pliki .a (lub w .lib systemu Windows). Cały kod związany z biblioteką znajduje się w tym pliku i jest on bezpośrednio powiązany z programem w czasie kompilacji. Program korzystający z biblioteki statycznej pobiera kopie kodu, którego używa, z biblioteki statycznej i czyni go częścią programu. [Windows ma również pliki .lib, które są używane do odwoływania się do plików .dll, ale działają one tak samo jak pierwszy].

Każda metoda ma zalety i wady:

  • Biblioteki współdzielone zmniejszają ilość kodu powielanego w każdym programie korzystającym z biblioteki, dzięki czemu pliki binarne są małe. Pozwala także zastąpić współdzielony obiekt tym, który jest funkcjonalnie równoważny, ale może mieć dodatkowe korzyści w zakresie wydajności bez konieczności ponownej kompilacji programu, który z niego korzysta. Udostępniane biblioteki będą jednak wiązały się z niewielkim dodatkowym kosztem wykonania funkcji, a także kosztem ładowania w czasie wykonywania, ponieważ wszystkie symbole w bibliotece muszą być połączone z używanymi przez nich rzeczami. Dodatkowo biblioteki współdzielone mogą być ładowane do aplikacji w czasie wykonywania, co jest ogólnym mechanizmem implementacji binarnych systemów wtyczek.

  • Biblioteki statyczne zwiększają całkowity rozmiar pliku binarnego, ale oznacza to, że nie trzeba nosić ze sobą kopii używanej biblioteki. Ponieważ kod jest podłączony podczas kompilacji, nie ma żadnych dodatkowych kosztów ładowania w czasie wykonywania. Kod jest po prostu dostępny.

Osobiście wolę biblioteki współdzielone, ale używam bibliotek statycznych, gdy muszę upewnić się, że plik binarny nie ma wielu zewnętrznych zależności, które mogą być trudne do spełnienia, takich jak określone wersje standardowej biblioteki C ++ lub określone wersje biblioteki Boost C ++.

Petesz
źródło
2
„zamień współdzielony obiekt na ... funkcjonalnie równoważny, ale może [poprawić] wydajność”: w szczególności równoważne funkcje skierowane do dzwoniącego w semantycznym użyciu API (interfejs programowania aplikacji: sygnatury funkcji i zmienne, w tym typy), ale po stronie implementacji funkcjonalność może różnić się więcej niż perf .: np. funkcja zawsze loguje się do pliku -> także loguje się do serwera TCP: oczekiwany port w $ MY_APP_LOG_SERVER.
Tony Delroy
1
„[.sos ponoszą] niewielki dodatkowy koszt wykonania funkcji” - jest to możliwe (jeśli grupy funkcji / kolejność zostały zoptymalizowane pod kątem lokalizacji pamięci podręcznej w łączu statycznym lub z powodu osobliwości w systemie operacyjnym / module ładującym / kompilatorze / takich jak cross -segment / large-pointer perf. kary), ale w wielu ustawieniach architektury / kompilatora dynamiczny linker łata wywołanie, aby utworzyć dokładnie takie same kody maszyn wywołujących.
Tony Delroy
2
„Ponieważ kod jest łączony w czasie kompilacji, nie ma żadnych dodatkowych kosztów ładowania w czasie wykonywania. Kod jest po prostu dostępny”. - tak i nie ... to wszystko jest w pliku wykonywalnym gotowym do stronicowania, jeśli wykonanie tego wymaga, ale - począwszy od sytuacji, w której twój program nie uruchomił się wystarczająco wcześnie, aby być w pamięci podręcznej - z bibliotekami współdzielonymi jest to możliwe (czasami prawdopodobne lub pewne), że system operacyjny, sterownik lub inny uruchomiony program załaduje już tę samą bibliotekę współdzieloną, z której chce korzystać Twoja aplikacja, w którym to przypadku może znajdować się w pamięci podręcznej, a program uruchamia się i działa szybciej.
Tony Delroy
15
To, czego niektórzy nie wspomnieli, to fakt, że dzięki bibliotekom statycznym kompilator wie, jakich funkcji potrzebuje Twoja aplikacja, a następnie może go zoptymalizować, włączając tylko te funkcje. To może znacznie zmniejszyć rozmiar biblioteki, szczególnie jeśli używasz tylko bardzo małego podzbioru naprawdę dużej biblioteki!
jduncanator,
1
Ta odpowiedź może być lepiej zorganizowana. Przydatne byłoby utworzenie list punktowanych dla zalet / wad lub tabeli, aby pokazać różnice w każdym wymiarze, w którym występuje różnica.
ElefEnt
377

Biblioteka statyczna jest jak księgarnia, a biblioteka współdzielona jest jak ... biblioteka. W pierwszym przypadku otrzymujesz własną kopię książki / funkcji, którą możesz zabrać do domu; z tym ostatnim ty i wszyscy inni idziecie do biblioteki, aby korzystać z tej samej książki / funkcji. Tak więc każdy, kto chce korzystać z (współdzielonej) biblioteki, musi wiedzieć, gdzie ona jest, ponieważ musisz „iść” po książkę / funkcję. Dzięki statycznej bibliotece książka / funkcja należy do ciebie i trzymasz ją w swoim domu / programie, a kiedy już ją posiadasz, nie obchodzi cię, gdzie i kiedy ją masz.

Paul Richter
źródło
70

Uproszczony:

  • Łączenie statyczne: jeden duży plik wykonywalny
  • Dynamiczne linkowanie: mały plik wykonywalny plus jeden lub więcej plików biblioteki (pliki .dll w systemie Windows, .so w systemie Linux lub .dylib w systemie macOS)
StackedCrooked
źródło
1
Ta odpowiedź jest dla mnie najlepsza, ponieważ jest praktyczna. Ma to o wiele większy sens niż metafora, która nie mówi o tym, co faktycznie dzieje się w komputerze. Wiedząc, że tak się dzieje, po prostu intuicyjnie znam wszystkie inne implikacje.
off99555,
36

W przypadku biblioteki statycznej kod jest wyodrębniany z biblioteki przez konsolidator i używany do zbudowania ostatecznego pliku wykonywalnego w punkcie kompilacji / kompilacji aplikacji. Ostateczny plik wykonywalny nie ma zależności od biblioteki w czasie wykonywania

W przypadku biblioteki współużytkowanej kompilator / linker sprawdza, czy nazwy, które łączysz, istnieją w bibliotece podczas budowania aplikacji, ale nie przenosi ich kodu do aplikacji. W czasie wykonywania biblioteka współdzielona musi być dostępna.

Sam język programowania C nie ma pojęcia bibliotek statycznych ani współdzielonych - są one całkowicie funkcją implementacyjną.

Osobiście wolę używać bibliotek statycznych, ponieważ upraszcza to dystrybucję oprogramowania. Jest to jednak opinia, w stosunku do której w przeszłości przelano wiele (symbolicznej) krwi.


źródło
5
+1 za „Sam język programowania C nie ma pojęcia o bibliotekach statycznych ani współdzielonych - są one całkowicie funkcją implementacyjną”.
Tiger
1
Cześć anon / @Tiger, dlaczego powiedziałeś „Sam język programowania C nie ma pojęcia bibliotek statycznych ani współdzielonych - są one całkowicie funkcją implementacyjną”. Czy możesz wyjaśnić trochę szczegółowo lub wskazać mi odpowiednie odniesienie?
Sunil Shahu
@SunilShahu Sposób, w jaki program jest skompilowany i powiązany jest specyficzny dla używanego kompilatora i linkera, tj. Konkretnej implementacji języka. Specyfikacje językowe na ogół nie opisują sposobu implementacji lub budowy języków, a jedynie funkcjonalność, składnię, gramatykę itp.
JC Rocamonde
@SunilShahu bardziej oczywistymi przykładami mogą być JavaScript, na przykład, gdy specyfikacja (EcmaScript) opisuje funkcje języka, ale to różni dostawcy dostarczają interpretery JS (na przykład silniki przeglądarki lub Node.js). Z drugiej strony język programowania Python ma kilka implementacji. Oficjalnym jest CPython, ale są też inne napisane w innych językach.
JC Rocamonde
31

Biblioteki statyczne są kompilowane jako część aplikacji, podczas gdy biblioteki współdzielone nie są. Gdy dystrybuujesz aplikację zależną od współdzielonych bibliotek, biblioteki, np. biblioteki dll w MS Windows muszą być zainstalowane.

Zaletą bibliotek statycznych jest to, że użytkownik uruchamiający aplikację nie wymaga żadnych zależności - np. Nie musi aktualizować swojej biblioteki DLL. Wadą jest to, że twoja aplikacja jest większa, ponieważ dostarczasz ją ze wszystkimi potrzebnymi bibliotekami.

Oprócz udostępniania mniejszych aplikacji, biblioteki współdzielone oferują użytkownikowi możliwość korzystania z ich własnych, być może lepszych wersji bibliotek, zamiast polegać na jednej, która jest częścią aplikacji

Tarski
źródło
3
DLL piekło, jak wiadomo
gheese
1
„Biblioteki statyczne są kompilowane jako część aplikacji” ... biblioteki statyczne są kompilowane jako biblioteki statyczne i łączone jako część aplikacji
idclev 463035818
19

Najważniejszą zaletą bibliotek współdzielonych jest to, że w pamięci jest załadowana tylko jedna kopia kodu, bez względu na to, ile procesów korzysta z biblioteki. W przypadku bibliotek statycznych każdy proces otrzymuje własną kopię kodu. Może to prowadzić do znacznego marnowania pamięci.

OTOH, zaletą bibliotek statycznych jest to, że wszystko jest zawarte w twojej aplikacji. Więc nie musisz się martwić, że klient będzie miał odpowiednią bibliotekę (i wersję) dostępną w swoim systemie.

Jasmeet
źródło
1
obraz wykonywalny jest większy zarówno na dysku, jak i w pamięci, podczas korzystania ze statycznych bibliotek lib.
JustJeff
To prawda, do tego właśnie nawiązywałem, kiedy powiedziałem, że wszystko jest zawarte w twojej aplikacji.
Jasmeet,
Ponadto .sopliki w systemach * nix są rodzajem biblioteki współdzielonej (dynamicznej).
snr
6

Oprócz wszystkich innych odpowiedzi, jedna jeszcze nie wspomniana sprawa to oddzielenie:

Pozwólcie, że powiem o kodzie produkcyjnym w świecie rzeczywistym, z którym miałem do czynienia:

Bardzo duże oprogramowanie, złożone z> 300 projektów (ze studiem wizualnym), zbudowane głównie jako statyczna biblioteka lib, a na końcu wszystkie połączone w jeden wielki plik wykonywalny, możesz mieć następujące problemy:

-Link czas jest bardzo długi. Możesz skończyć z ponad 15 minutami łącza, powiedzmy 10s czasu kompilacji - niektóre narzędzia są na kolanach z tak dużym plikiem wykonywalnym, jak narzędzia do sprawdzania pamięci, które muszą instrumentować kod. Możesz osiągnąć granice, które uważano za głupców.

Bardziej problematyczne jest oddzielenie oprogramowania: na tym prawdziwym przykładzie pliki nagłówków każdego projektu były dostępne dla innych projektów. W rezultacie jeden programista bardzo łatwo dodał zależności; chodziło tylko o włączenie nagłówka, ponieważ link na końcu pozwoli znaleźć symbole. Kończy się to okropnymi zależnościami rowerowymi i kompletnym bałaganem.

W przypadku biblioteki współdzielonej jest to trochę dodatkowa praca, ponieważ programista musi edytować system kompilacji projektu, aby dodać bibliotekę zależną. Zauważyłem, że kod współdzielonej biblioteki oferuje czystszy kod API.

drzewo sandałowe
źródło
2
-------------------------------------------------------------------------
|  +-  |    Shared(dynamic)       |   Static Library (Linkages)         |
-------------------------------------------------------------------------
|Pros: | less memory use          |   an executable, using own libraries|
|      |                          |     ,coming with the program,       |
|      |                          |   doesn't need to worry about its   |
|      |                          |   compilebility subject to libraries|
-------------------------------------------------------------------------
|Cons: | implementations of       |   bigger memory uses                |
|      | libraries may be altered |                                     |
|      | subject to OS  and its   |                                     |
|      | version, which may affect|                                     |
|      | the compilebility and    |                                     |
|      | runnability of the code  |                                     |
-------------------------------------------------------------------------
snr
źródło