Co znajduje się w bibliotece DLL i jak to działa?

86

Zawsze odwołuję się do bibliotek DLL w moim kodzie C #, ale pozostały one nieco tajemnicą, którą chciałbym wyjaśnić. To rodzaj zrzutu mózgów pytań dotyczących bibliotek DLL.

Rozumiem, że biblioteka DLL jest biblioteką połączoną dynamicznie, co oznacza, że ​​inny program może uzyskać dostęp do tej biblioteki w czasie wykonywania, aby uzyskać „funkcjonalność”. Należy jednak wziąć pod uwagę następujący projekt ASP.NET z Web.dlli Business.dll( Web.dlljest to funkcja frontonu i odwołuje się Business.dlldo typów i metod).

  1. W którym momencie następuje Web.dllłącze dynamiczne Business.dll? Zauważasz dużo w Windowsie, gdy dysk twardy w systemie Windows pęka z powodu pozornie małych zadań podczas korzystania z programu Word (itp.) I myślę, że program Word działa i dynamicznie łączy funkcje z innych bibliotek DLL?

    1a. Ponadto, co ładuje i łączy bibliotekę DLL - system operacyjny lub pewne środowisko wykonawcze, takie jak platforma .NET?

    1b. Jak wygląda proces „łączenia”? Czy przeprowadzane są kontrole zgodności? Ładowanie do tej samej pamięci? Co właściwie oznacza linkowanie?

  2. Co właściwie wykonuje kod w bibliotece DLL? Czy jest wykonywany przez procesor, czy też jest inny etap tłumaczenia lub kompilacji, zanim procesor zrozumie kod wewnątrz biblioteki DLL?

    2a. W przypadku biblioteki DLL wbudowanej w C # .NET, co to uruchamia: platforma .NET czy bezpośrednio system operacyjny?

  3. Czy biblioteka DLL z Linuksa działa w systemie Windows (jeśli coś takiego istnieje), czy też są one specyficzne dla systemu operacyjnego?

  4. Czy biblioteki DLL są specyficzne dla określonej struktury? Czy biblioteka DLL zbudowana w języku C # .NET może być używana przez bibliotekę DLL utworzoną na przykład w języku Borland C ++?

    4a. Jeśli odpowiedź na 4 brzmi „nie”, to jaki jest cel biblioteki DLL? Dlaczego różne frameworki nie używają własnych formatów dla plików połączonych? Na przykład: plik .exe wbudowany w .NET wie, że typ pliku .abc jest czymś, co może połączyć z jego kodem.

  5. Wracając do Web.dll/ Business.dllprzykład - aby uzyskać typ klasy klienta trzeba odwołać Business.dllod Web.dll. Musi to oznaczać, że Business.dllzawiera jakąś specyfikację tego, czym właściwie jest klasa klienta. Gdybym skompilował swój Business.dllplik, powiedzmy, w Delphi: czy C # zrozumie go i będzie w stanie utworzyć klasę klienta, czy jest tam jakieś informacje w nagłówku lub coś, co mówi „hej, przepraszam, możesz używać mnie tylko z innej biblioteki Delphi DLL” ?

    5a. To samo dotyczy metod; czy mogę napisać CreateInvoice()metodę w bibliotece DLL, skompilować ją w C ++, a następnie uzyskać do niej dostęp i uruchomić ją z poziomu C #? Co mnie powstrzymuje lub pozwala?

  6. Jeśli chodzi o przechwytywanie bibliotek DLL, z pewnością zastępcza (zła) biblioteka DLL musi zawierać dokładne sygnatury i typy metod, jak ta, która jest przejmowana. Przypuszczam, że nie byłoby to trudne, gdybyś mógł dowiedzieć się, jakie metody były dostępne w oryginalnej bibliotece DLL.

    6a. Co w moim programie C # decyduje, czy mogę uzyskać dostęp do innej biblioteki DLL? Jeśli moja przejęta biblioteka DLL zawierała dokładnie te same metody i typy, co oryginał, ale została skompilowana w innym języku, czy zadziała?

Co to jest importowanie i rejestracja bibliotek DLL?

Remotec
źródło
21
To pytanie może być najdłuższą odpowiedzią w historii SO.
Matti Virkkunen
4
Powinno być 12 oddzielnych pytań.
Henk Holterman
2
To niesamowite pytanie, ale naprawdę zgadzam się z @Chaos i @Matti. To pytanie wymaga większej uwagi i można / powinno się je podzielić na kilka różnych pytań.
Chris Thompson,
3
To był
mały
1
Powinna już być wiki społeczności.
leppie

Odpowiedzi:

74

Przede wszystkim musisz zrozumieć różnicę między dwoma bardzo różnymi rodzajami bibliotek DLL. Firma Microsoft zdecydowała się na stosowanie tych samych rozszerzeń plików (.exe i .dll) zarówno w przypadku .NET (kod zarządzany), jak i kodu natywnego, jednak biblioteki DLL kodu zarządzanego i natywne biblioteki DLL są bardzo różne w środku.

1) W którym momencie plik web.dll łączy się dynamicznie z plikiem business.dll? Zauważasz dużo w Windowsie, gdy dysk twardy w systemie Windows się marszczy przy pozornie małych zadaniach podczas korzystania z programu Word itp. I myślę, że ten program Word działa i dynamicznie łączy funkcje z innych bibliotek DLL?

1) W przypadku .NET biblioteki DLL są zwykle ładowane na żądanie, gdy wykonywana jest pierwsza metoda próbująca uzyskać dostęp do czegokolwiek z biblioteki DLL. Dlatego możesz pobrać TypeNotFoundExceptions w dowolnym miejscu w kodzie, jeśli nie można załadować biblioteki DLL. Kiedy coś takiego jak Word nagle zaczyna często uzyskiwać dostęp do dysku twardego, prawdopodobnie następuje zamiana (pobieranie danych, które zostały zamienione na dysk, aby zrobić miejsce w pamięci RAM)

1a) Dodatkowo, co ładuje i łączy bibliotekę DLL - system operacyjny lub część środowiska wykonawczego, na przykład platformę .Net?

1a) W przypadku zarządzanych bibliotek DLL ładuje się środowisko .NET, kompiluje JIT (kompiluje kod bajtowy .NET do kodu natywnego) i łączy biblioteki DLL. W przypadku natywnych bibliotek DLL jest to składnik systemu operacyjnego, który ładuje i łączy bibliotekę DLL (kompilacja nie jest konieczna, ponieważ natywne biblioteki DLL zawierają już kod natywny).

1b) Jak wygląda proces „łączenia”? Czy sprawdza się zgodność? Ładowanie do tej samej pamięci? Co właściwie oznacza linkowanie?

1b) Łączenie występuje wtedy, gdy odniesienia (np. Wywołania metod) w kodzie wywołującym do symboli (np. Metod) w bibliotece DLL są zastępowane faktycznymi adresami rzeczy w bibliotece DLL. Jest to konieczne, ponieważ ostateczne adresy elementów w bibliotece DLL nie mogą być znane przed załadowaniem ich do pamięci.

2) Co właściwie wykonuje kod w bibliotece DLL? Czy jest wykonywany przez procesor, czy też jest inny etap tłumaczenia lub kompilacji, zanim procesor zrozumie kod wewnątrz biblioteki DLL?

2) W systemie Windows pliki .exe i .dll są identyczne. Natywne pliki .exe i .dll zawierają kod natywny (ten sam, który wykonuje procesor), więc nie ma potrzeby tłumaczenia. Zarządzane pliki .exe i .dll zawierają kod bajtowy .NET, który jest pierwszą kompilacją JIT (przetłumaczoną na kod macierzysty).

2a) W przypadku biblioteki DLL zbudowanej z C # .net, co to uruchamia? Framework .Net czy bezpośrednio system operacyjny?

2a) Po skompilowaniu kodu JIT jest on uruchamiany dokładnie tak samo, jak każdy kod.

3) Czy biblioteka DLL z, powiedzmy, Linuksa działa w systemie Windows (jeśli coś takiego istnieje), czy też są one specyficzne dla systemu operacyjnego?

3) Zarządzane biblioteki DLL mogą działać tak, jak są, pod warunkiem, że platformy na obu platformach są aktualne, a ktokolwiek napisał bibliotekę DLL, celowo nie naruszył zgodności przy użyciu wywołań natywnych. Natywne biblioteki DLL nie będą działać tak jak w, ponieważ formaty są różne (nawet jeśli kod maszynowy w środku jest taki sam, jeśli oba są przeznaczone dla tej samej platformy procesora). Nawiasem mówiąc, w systemie Linux pliki „DLL” są nazywane plikami .so (obiektami współdzielonymi).

4) Czy są one specyficzne dla określonej struktury? Czy biblioteka DLL zbudowana przy użyciu C # .Net może być używana przez bibliotekę DLL zbudowaną w języku Borland C ++ (tylko przykład)?

4) Zarządzane biblioteki DLL są specyficzne dla platformy .NET, ale naturalnie działają z dowolnym zgodnym językiem. Natywne biblioteki DLL są kompatybilne, o ile wszyscy używają tych samych konwencji (konwencji wywoływania (w jaki sposób argumenty funkcji są przekazywane na poziomie kodu maszynowego), nazewnictwo symboli itp.)

5) Wracając do przykładu web.dll / business.dll. Aby uzyskać typ klienta, muszę odwołać się do business.dll z web.dll. Musi to oznaczać, że business.dll zawiera specyfikację tego, czym właściwie jest klasa klienta. Gdybym skompilował mój plik business.dll w, powiedzmy, że Delphi C # to zrozumie i będzie w stanie utworzyć klasę klienta - lub czy istnieje jakiś rodzaj informacji w nagłówku lub coś, co mówi "hej, przepraszam, możesz używać mnie tylko z innej biblioteki delphi dll" .

5) Zarządzane biblioteki DLL zawierają pełny opis każdej klasy, metody, pola itp., Które zawierają. AFAIK Delphi nie obsługuje .NET, więc utworzyłoby natywne biblioteki DLL, których nie można od razu użyć w .NET. Prawdopodobnie będziesz mógł wywoływać funkcje za pomocą PInvoke, ale definicje klas nie zostaną znalezione. Nie używam Delphi, więc nie wiem, jak przechowuje informacje o typach za pomocą bibliotek DLL. Na przykład C ++ opiera się na plikach nagłówkowych (.h), które zawierają deklaracje typu i muszą być dystrybuowane z biblioteką DLL.

6) Jeśli chodzi o przechwytywanie DLL, z pewnością zastępcza (zła) biblioteka DLL musi zawierać dokładne sygnatury metod, takie jak ten, który jest przejmowany. Przypuszczam, że nie byłoby to trudne, gdybyś mógł dowiedzieć się, jakie metody itp. Były dostępne w oryginalnej bibliotece DLL.

6) Rzeczywiście, nie jest to trudne, jeśli można łatwo zmienić bibliotekę DLL. Aby tego uniknąć, można użyć podpisywania kodu. Aby ktoś mógł zastąpić podpisaną bibliotekę DLL, musiałby znać klucz podpisujący, który utrzymywał w tajemnicy.

6a) Trochę tu powtarzam pytanie, ale to wraca do tego, co w moim programie C # decyduje, czy mogę uzyskać dostęp do innej biblioteki DLL? Jeśli moja przejęta biblioteka DLL zawierała dokładnie te same metody i typy, co oryginał, ale została skompilowana w innym języku, czy zadziała?

6a) Będzie działać, o ile jest zarządzaną biblioteką DLL, utworzoną w dowolnym języku .NET.

  • Co to jest importowanie DLL? i rejestracja dll?

„Importowanie DLL” może oznaczać wiele rzeczy, zwykle oznacza odwoływanie się do pliku DLL i używanie jego elementów.

Rejestracja DLL to coś, co robi się w systemie Windows, aby globalnie zarejestrować pliki DLL jako składniki COM, aby udostępnić je dowolnemu oprogramowaniu w systemie.

Matti Virkkunen
źródło
3
Dodałbym do # 4, że .NET może tłumaczyć biblioteki DLL, dzięki czemu są one zgodne z każdym rodzimym programem, który rozumie / używa COM (Common Object Model). Bardzo dobre odpowiedzi.
MerickOWA
7

Plik .dll zawiera skompilowany kod, którego możesz użyć w swojej aplikacji.

Czasami narzędzie użyte do skompilowania pliku .dll ma znaczenie, a czasami nie. Jeśli możesz odwołać się do pliku .dll w swoim projekcie, nie ma znaczenia, które narzędzie zostało użyte do zakodowania udostępnionych funkcji .dll.

Łączenie odbywa się w czasie wykonywania, w przeciwieństwie do bibliotek połączonych statycznie, takich jak klasy, które łączą się w czasie kompilacji.

Możesz myśleć o .dll jako o czarnej skrzynce, która zawiera coś, czego aplikacja potrzebuje, a czego nie chcesz pisać samodzielnie. Tak, ktoś rozumiejący podpis .dll mógłby utworzyć inny plik .dll z innym kodem wewnątrz niego, a aplikacja wywołująca nie mogłaby rozpoznać różnicy.

HTH

Beth
źródło
6

1) W którym momencie plik web.dll łączy się dynamicznie z plikiem business.dll? Zauważasz dużo w Windowsie, gdy dysk twardy w systemie Windows się marszczy przy pozornie małych zadaniach podczas korzystania z programu Word itp. I myślę, że ten program Word działa i dynamicznie łączy funkcje z innych bibliotek DLL?

1) Myślę, że mylisz linkowanie z ładowaniem. Łącze jest wtedy, gdy wszystkie kontrole i salda są testowane, aby upewnić się, że to, o co proszono, jest dostępne. W czasie wczytywania części dll są ładowane do pamięci lub zamieniane w plik stronicowania. To jest aktywność HD, którą widzisz.

Łączenie dynamiczne różni się od łączenia statycznego tym, że w łączeniu statycznym cały kod obiektowy jest umieszczany w głównym pliku .exe w czasie łączenia. W przypadku dynamicznego łączenia kod obiektowy jest umieszczany w oddzielnym pliku (dll) i ładowany w innym czasie niż plik .exe.

Łączenie dynamiczne może być niejawne (tzn. Aplikacja łączy się z biblioteką importu) lub jawne (tj. Aplikacja używa LoadLibrary (ex) do załadowania biblioteki DLL).

W niejawnym przypadku / DELAYLOAD może służyć do odroczenia ładowania biblioteki dll do czasu, gdy aplikacja faktycznie tego potrzebuje. W przeciwnym razie przynajmniej niektóre jego części są ładowane (mapowane do przestrzeni adresowej procesu) jako część inicjalizacji procesu. Biblioteka dll może również zażądać, aby nigdy nie została wyładowana, gdy proces jest aktywny.

COM używa LoadLibrary do ładowania bibliotek dll COM. Zwróć uwagę, że nawet w niejawnym przypadku system używa czegoś podobnego do LoadLibrary do ładowania biblioteki dll podczas uruchamiania procesu lub przy pierwszym użyciu.

2) Co właściwie wykonuje kod w bibliotece DLL? Czy jest wykonywany przez procesor, czy też jest inny etap tłumaczenia lub kompilacji, zanim procesor zrozumie kod wewnątrz biblioteki DLL?

2) Pliki DLL zawierają kod obiektowy, podobnie jak .exes. Format pliku dll jest prawie identyczny z formatem pliku exe. Słyszałem, że tylko jeden bit różni się w nagłówkach obu plików.

W przypadku biblioteki DLL zbudowanej z C # .net, uruchamia ją struktura .Net.

3) Czy biblioteka DLL z, powiedzmy, Linuksa działa w systemie Windows (jeśli coś takiego istnieje), czy też są one specyficzne dla systemu operacyjnego?

3) Biblioteki DLL są specyficzne dla platformy.

4) Czy są one specyficzne dla określonej struktury? Czy biblioteka DLL zbudowana przy użyciu C # .Net może być używana przez bibliotekę DLL zbudowaną w języku Borland C ++ (tylko przykład)?

4) Biblioteki DLL mogą współpracować z innymi frameworkami, jeśli zachowa się szczególną ostrożność lub zostanie napisany dodatkowy kod kleju.

Biblioteki DLL są bardzo przydatne, gdy firma sprzedaje wiele produktów, których możliwości się pokrywają. Na przykład utrzymuję rastrowy plik dll we / wy, który jest używany przez ponad 30 różnych produktów w firmie. Jeśli masz zainstalowanych wiele produktów, jedno uaktualnienie biblioteki dll może zaktualizować wszystkie produkty do nowych formatów rastrowych.

5) Wracając do przykładu web.dll / business.dll. Aby uzyskać typ klienta, muszę odwołać się do business.dll z web.dll. Musi to oznaczać, że business.dll zawiera specyfikację tego, czym właściwie jest klasa klienta. Gdybym skompilował mój plik business.dll w, powiedzmy, że Delphi C # to zrozumie i będzie w stanie utworzyć klasę klienta - lub czy istnieje jakiś rodzaj informacji w nagłówku lub coś, co mówi "hej, przepraszam, możesz używać mnie tylko z innej biblioteki delphi dll" .

5) W zależności od platformy, możliwości biblioteki DLL są prezentowane na różne sposoby, poprzez pliki .h, .tlb lub w inny sposób na .net.

6) Jeśli chodzi o przechwytywanie DLL, z pewnością zastępcza (zła) biblioteka DLL musi zawierać dokładne sygnatury metod, takie jak ten, który jest przejmowany. Przypuszczam, że nie byłoby to trudne, gdybyś mógł dowiedzieć się, jakie metody itp. Były dostępne w oryginalnej bibliotece DLL.

6) dumpbin / export i dumbin / import są interesującymi narzędziami do wykorzystania w plikach .exe i .dlls

Edgman
źródło
3) DLL jest specyficzne dla platformy
Henk Holterman