2011-01-25 10 views
7

Kiedy należy implicite lub jawnie link do biblioteki DLL i jakie są powszechne praktyki lub pułapki?Implicit vs. Explicit linking to DLL

+1

co masz na myśli przez wyraźne kontra ukryte? masz na myśli używanie LoadLibrary lub statycznego linkowania? – tenfour

+1

@tenfour niejawny jest gdy używasz .h i musisz połączyć z .lib i jawnie, gdy użyjesz odpowiednio LoadLibrary i GetProcAddress. Statyczne łączenie to kolejna guma do żucia. – Shinnok

+1

Czasem używasz jawnie, gdy nie masz do dyspozycji pliku .lib. –

Odpowiedz

8

Dość rzadko można jawnie połączyć bibliotekę DLL. Głównie dlatego, że jest bolesny i podatny na błędy. Musisz napisać deklarację wskaźnika funkcji dla wyeksportowanej funkcji i uzyskać prawo do LoadLibrary + GetProcAddress + FreeLibrary. Można to zrobić tylko wtedy, gdy potrzebna jest zależność środowiska wykonawczego od biblioteki DLL typu plug-in lub jeśli chcemy wybierać z zestawu bibliotek DLL na podstawie konfiguracji. Lub poradzić sobie z wersją, funkcja API dostępna tylko w późniejszych wersjach Windows. Jawne łączenie jest domyślne dla bibliotek COM i .NET DLL.

Więcej informacji dodatkowych w tym MSDN Library article.

4

Zakładam, że odwołujesz się do łączenia za pomocą .lib vs dynamicznie ładując bibliotekę DLL przy użyciu LoadLibrary().

Załadowanie statycznej biblioteki DLL za pomocą linku do jej .lib jest ogólnie bezpieczniejsze. Etap łączenia sprawdza, czy wszystkie punkty wejścia istnieją w czasie kompilacji i nie ma szansy, aby załadować bibliotekę DLL, która nie ma oczekiwanej funkcji. Łatwiej też nie trzeba używać GetProcAddress().

Zasadniczo należy stosować dynamiczne ładowanie tylko wtedy, gdy jest to absolutnie wymagane.

5

Zgadzam się z innymi, którzy już odpowiedzieli (Hans Passant and shoosh). Chcę dodać tylko dwie rzeczy:

1) Jeden wspólny scenariusz, gdy trzeba użyć LoadLibrary i GetProcAddress jest następujący: chcesz wykorzystać jakieś nowe API istniejącego w nowych wersjach tylko Windows, ale API nie są krytyczne w swojej podanie. Więc przetestuj z LoadLibrary i GetProcAddress, czy funkcja, którą potrzebujesz, istnieje i użyj go w przypadku. To, co robi twój program, jeśli funkcje nie istnieją, zależy od twojej implementacji.

2) Istnieje jedna ważna opcja, której nie dotyczy pytanie: delayed loading of DLLs. W takim przypadku system operacyjny załaduje bibliotekę DLL po wywołaniu jednej z jej funkcji, a nie po uruchomieniu aplikacji. Umożliwia korzystanie z bibliotek importu (pliki .lib) w niektórych scenariuszach, w których na pierwszy rzut oka należy zastosować jawne łączenie. Ponadto poprawia czas uruchamiania aplikacji i jest szeroko stosowany przez sam system Windows. Więc zalecana jest również droga.

+0

Ładowanie opóźnienia jest realizowane przez program Visual Studio linker, a nie system operacyjny. Wstawia odpowiednie wywołania 'LoadLibrary' i' GetProcAddress'. System operacyjny nie jest świadomy, kto wykonał te połączenia. Właśnie dlatego działa z powrotem do Window 95, mimo że funkcja została wprowadzona w 98. – MSalters

+0

@MSalters: Mylisz się. Program Deployment Executable (PE) wykorzystujący obciążenie opóźnione ma dodatkową sekcję 'IMAGE_DIRECTORY_DRY_DELAY_IMPORT'. – Oleg