Windows ne connaît qu'un seul type de DLL, mais offre deux possibilités à un programme pour accéder à une DLL : Pendant la procédure de chargement par le biais du Shell ou pendant l'exécution en appelant lui-même les fonctions API correspondantes. Dans le premier cas, on parle de " load time dynamic linking " ( lien dynamique au chargement ), dans le deuxième de " run time dynamic linking " ( lien dynamique pendant l'exécution).
Avec " load time dynamic linking ", on indique déjà dans le code source d'un programme que l'on souhaite accéder à une DLL et à toutes les fonctions qui la composent en intégrant le fichier Include approprié et en appelant tout simplement la fonction. Les fonctions DLL sont traitées dans le code programme exactement de la même façon que les fonctions externes en provenance d'autres modules. Les informations correspondantes sur les fonctions et les DLL nécessaires sont enregistrées dans le fichier EXE du programme. Lorsque le programme est lancé les DLL nécessaires sont automatiquement chargées en mémoire et le lien est établi.
Pour que le compilateur puisse prendre
les dispositions nécessaires à appeler les fonctions DLL, dès
la compilation du code source, il lui faut disposer de ce que l'on appelle le
fichier LIB qui contient toutes les informations contenues dans la DLL. Du fait
que la liaison entre l'application et la DLL est statique et qu'elle n'est plus
modifiée pour l'exécution, on parle également ici de "
load time static linking " (lien statique au chargement).
Load-Time-Linking est la méthode préférentielle qui est
utilisée pour appeler la majorité des fonctions WIN32-API car
elle ne présente pas de difficulté particulière et que
le programmeur ne doit s'occuper de rien. Il faut utiliser cette méthode
quand on connaît les fonctions DLL auxquelles on veut faire appel ainsi
que les fichiers DLL dans lesquels elles se trouvent.
Run-Time-Linking, n'est justifiée que lorsque le nom de la DLL
nécessaire et éventuellement les noms des fonctions à y
appeler ne peuvent être déterminés que pendant l'exécution
du programme. Windows utilise ce concept, par exemple, pour communiquer avec
les gestionnaires d'imprimante et les gestionnaires multimédias. C'est
la base de données de registration qui indiquent aux services du système
les gestionnaires qui sont installés et les DLL qui doivent ainsi être
chargées pour pouvoir accéder aux fonctions nécessaires.
Run-Time-Linking nécessite en conséquence la collaboration active de l'application concernée, car les fonctions à exécuter ne peuvent pas être déclarées à l'intérieur du code source. Pour son exécution, une telle application appelle tout d'abord la fonction API LoadLibrary() afin de charger un fichier DLL quelconque et d'y accéder. Les adresses des fonctions requises à l'intérieur de la DLL sont ensuite déterminées à l'aide de la fonction API GetProcAddress()
La fonction FreeLibrary() sert à
supprimer de l'application une DLL préalablement chargée par le
biais de LoadLibrary(). Elle décrémente le compteur utilisateur
de la DLL en question et la supprime de l'application dès que le compteur
est à 0.
Cependant FreeLibrary() peut non seulement être appelée
d'une application, mais aussi par une DLL désirant se décharger.
En réponse, par exemple, à une fonction appelée par l'application
qui dit à la DLL : " je n'ai plus besoin de toi ". Si, pendant
son exécution, la DLL a créé plusieurs Thread qui
commandent son exécution, il se produit alors, dans certaines circonstances,
un petit problème logistique lors de l'utilisation de FreeLibrary().
Avant d'appeler FreeLibrary(), le DLL devrait tout d'abord terminer tous
les Thread créés. Mais sans Thread, la DLL est incapable
d'appeler FreeLibrary(). Il est donc nécessaire de conserver au
moins un Thread qui appellera FreeLibrary(). Mais du fait que
la DLL sera ainsi effacée de la mémoire, le Thread disparaîtra
lui aussi et ne pourra donc plus se terminer correctement. L'inverse n'est pas
non plus possible, car si le Thread s'efface d'abord lui-même par le biais
de ExitThread, il n'est ensuite plus en mesure d'appeler FreeLibrary().
La fonction FreeLibraryAndExitThread(), qui réalise les deux taches, offre une solution à ce problème. Elle décharge tout d'abord la DLL et termine ensuite le Thread appelant.