Výběr použité propojovací metody
Existují dva typy propojení: implicitní a explicitní.
Implicitní propojení
Implicitní propojení vzniká, pokud kód aplikace volá exportovanou funkci knihovny DLL.Pokud je zdrojový kód pro volání spustitelného souboru kompilován nebo sestaven, volání funkce knihovny DLL generuje externí odkaz na funkci v kódu objektu.Chcete-li přeložit tento externí odkaz, aplikace se musí propojit s importní knihovnou (soubor .lib) poskytovanou autorem knihovny DLL.
Importní knihovna obsahuje pouze kód, který načte knihovnu DLL a implementuje volání funkcí v knihovně DLL.Nalezení externí funkce v importní knihovně informuje propojovací program, že kód pro tuto funkci je v knihovně DLL.Chce-li propojovací program přeložit externí odkazy na knihovny DLL, jednoduše přidá informace do spustitelného souboru, který sdělí systému, kde najít kód knihovny DLL při spouštění procesu.
Při spuštění systému, program, který obsahuje dynamicky propojené odkazy, použije informace ze spustitelného souboru pro daný program pro nalezení požadované knihovny DLL.Pokud nelze nalézt knihovnu DLL, systém ukončí proces a zobrazí dialogové okno, které ohlásí chybu.V opačném případě systém namapuje moduly knihovny DLL do adresového prostoru procesu.
Pokud má některá z knihoven DLL funkci vstupního bodu (pro inicializaci a ukončení kódu), operační systém volá tuto funkci.Jeden z parametrů, který je předán funkci vstupního bodu, určuje kód, který označuje připojení knihovny DLL k procesu.Pokud funkce vstupního bodu nevrátí hodnotu TRUE, systém ukončí proces a ohlásí chybu.
Nakonec systém upraví spustitelný kód procesu tak, aby bylo možné poskytovat počáteční adresy pro funkce knihovny DLL.
Podobně jako ve zbytku kódu programu je kód knihovny DLL namapován na prostor adresy procesu při spuštění procesu a do paměti je načten pouze v případě potřeby.Atributy kódu PRELOAD a LOADONCALL, používány soubory .def, aby kontrolovali načítání v předchozích verzích systému Windows, již nemají význam.
Explicitní propojení
Většina aplikací používá implicitní propojení, protože je to nejsnazší metoda propojení, kterou lze použít.Existují však situace, kdy je nezbytné použít explicitní propojení.Zde jsou uvedeny některé běžné důvody použití explicitního propojení:
Aplikace neví název knihovny DLL, kterou bude muset načíst před spuštěním.Například by aplikace mohla potřebovat získat název knihovny DLL a exportovaných funkcí z konfiguračního souboru.
Proces, který používá implicitní propojení, je ukončen operačním systémem, pokud není nalezena knihovna DLL při spouštění procesu.Proces, který používá explicitní propojení, není v této situaci ukončen a může se pokusit zotavit z chyby.Například, proces by mohl oznámit uživateli chybu a požádat uživatele o určení jiné cesty ke knihovně DLL.
Proces, který používá implicitní propojení, je také ukončen v případě, že jakákoliv z knihoven DLL, která je propojena s funkcí DllMain, se nezdaří.Proces, který používá explicitní propojení, není v této situaci ukončen.
Aplikace, která implicitně odkazuje na mnoho knihoven DLL může být pomalá při spouštění, protože systém Windows načítá všechny knihovny DLL při načtení aplikace.Chcete-li zvýšit výkon při spouštění, aplikace může implicitně propojit ty knihovny DLL, které jsou potřebné ihned po načtení a počkat s explicitním propojením dalších knihoven DLL až pokud jsou potřeba.
Explicitní propojení odstraňuje nutnost propojení aplikace s importní knihovnou.Pokud změny v knihovně DLL způsobí změnu exportních řadových číslovek, aplikace, které používají explicitní propojení, není nutné znovu propojit (za předpokladu, že volají GetProcAddress s názvem funkce a nikoli s pořadovým číslem), zatímco aplikace, které používají implicitní propojení, je nutné znovu propojit do nové importní knihovny.
Jsou zde dvě nebezpečí, které byste měli mít na paměti při použití explicitního propojení:
Pokud má knihovna DLL funkci vstupního bodu DllMain, operační systém zavolá funkci v kontextu vlákna, která se nazývá LoadLibrary.Funkce vstupního bodu není volána, pokud je knihovna DLL již připojena k procesu z důvodu předchozího volání LoadLibrary bez odpovídajícího volání funkce FreeLibrary.Explicitní propojení může způsobit problémy, pokud knihovna DLL používá funkci DllMain pro inicializaci každého vlákna procesu, protože vlákna existující při volání LoadLibrary (nebo AfxLoadLibrary) nebudou inicializována.
Pokud knihovna DLL deklaruje statický rozsah dat jako například __declspec(vlákno), může to způsobit chybu ochrany v případě explicitního propojení.Poté, co je knihovna DLL načtena s LoadLibrary, způsobuje to chybu ochrany vždy, když kód odkazuje na tato data. (Statický rozsah dat zahrnuje globální i místní statické položky.) Proto při vytváření knihovny DLL byste se měli buď vyhnout použití místního úložného prostoru vlákna nebo informovat uživatele knihovny DLL o potenciálních problémech (v případě, že se pokoušejí o dynamické načítání).
Co chcete udělat?
O čem chcete vědět více?
Vyhledávací cesta používaná systémem Windows k nalezení knihovny DLL
Použití místního úložného prostoru vlákna v dynamické knihovně (sada Windows SDK)