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.dll
i Business.dll
( Web.dll
jest to funkcja frontonu i odwołuje się Business.dll
do typów i metod).
W którym momencie następuje
Web.dll
łącze dynamiczneBusiness.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?
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?
Czy biblioteka DLL z Linuksa działa w systemie Windows (jeśli coś takiego istnieje), czy też są one specyficzne dla systemu operacyjnego?
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.
Wracając do
Web.dll
/Business.dll
przykład - aby uzyskać typ klasy klienta trzeba odwołaćBusiness.dll
odWeb.dll
. Musi to oznaczać, żeBusiness.dll
zawiera jakąś specyfikację tego, czym właściwie jest klasa klienta. Gdybym skompilował swójBusiness.dll
plik, 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?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?
Odpowiedzi:
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 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) 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) Łą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) 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) Po skompilowaniu kodu JIT jest on uruchamiany dokładnie tak samo, jak każdy kod.
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) 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) 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) 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) Będzie działać, o ile jest zarządzaną biblioteką DLL, utworzoną w dowolnym języku .NET.
„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.
źródło
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
źródło
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) 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) Biblioteki DLL są specyficzne dla platformy.
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) 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) dumpbin / export i dumbin / import są interesującymi narzędziami do wykorzystania w plikach .exe i .dlls
źródło