Une bibliothèque de liens dynamiques est un ensemble de procédures et de fonctions qui peuvent être appelées par des applications et d'autres DLL. Elle contient du code ou des ressources publiques. Étant donné que le code de la DLL utilise la technologie de partage de mémoire, Windows accorde également à la DLL des autorisations plus élevées à certains endroits, de sorte que la DLL peut implémenter certaines fonctions qui ne peuvent pas être réalisées par des programmes ordinaires, telles que l'implémentation de Windows HOOK, ISAPI, etc. Dans le même temps, la DLL constitue également un moyen pratique de partager du code entre différentes langues. Par conséquent, la DLL est largement utilisée en programmation. Cet article explique comment créer et utiliser une DLL dans Delphi.
un. Mécanisme de partage de mémoire de la bibliothèque DLL
Du point de vue de l'utilisation, la DLL et l'unité sont très similaires. Elles peuvent toutes deux être appelées par d'autres modules du projet, mais il existe des différences dans leurs mécanismes de mise en œuvre internes. Si un module de programme utilise une instruction using pour référencer une unité, lorsque le compilateur compile le module, il le compilera avec l'unité et liera le code exécutable compilé au module de programme. C'est ainsi qu'un module de programme peut La raison de l'appel. procédures et fonctions dans l’unité référencée. Lorsque la même unité est référencée par plusieurs projets, chaque projet contient le code exécutable de l'unité. Lorsque plusieurs projets contenant l'unité sont exécutés en même temps, le code exécutable de l'unité sera mis à jour plusieurs fois avec différents projets transférés. dans la mémoire, provoquant un gaspillage de ressources mémoire. La DLL est différente. Même si elle est appelée par un certain projet, elle est toujours indépendante après la compilation, c'est-à-dire qu'après la compilation, une bibliothèque DLL forme un fichier exécutable distinct et n'est connectée à aucun autre fichier exécutable. La bibliothèque DLL n'est pas subordonnée à un projet spécifique. Lorsque plusieurs projets appellent la même bibliothèque DLL, seul le premier projet transfère la bibliothèque DLL dans la mémoire. Les autres projets ne transfèrent pas à plusieurs reprises la même bibliothèque DLL dans la mémoire, mais lisent depuis la mémoire. même zone de mémoire partagée. De plus, le code d'exécution de la DLL est transféré dynamiquement pendant l'exécution du programme, plutôt que d'être transféré dans la mémoire avec l'ensemble du projet lorsque le programme est en cours d'exécution. Cela peut éliminer les inconvénients causés par l'unité selon lesquels le même code occupe la mémoire à plusieurs endroits.
2. Création d'une bibliothèque DLL dans Delphi
Dans l'environnement Delphi, l'écriture d'une DLL n'est pas très différente de l'écriture d'une application générale. En fait, l'écriture des fonctions DLL en tant que corps principal d'une DLL ne nécessite aucun autre moyen particulier, à l'exception des différences de gestion de la mémoire et des ressources.
Le format des fichiers généraux du projet est :
Titre du projet PROgramme ;
utilise la clause ;
Corps du programme
Le format des fichiers de projet DLL est :
titre du projet de bibliothèque ;
utilise la clause ;
clause d'exportation ;
Corps du programme
Il existe deux différences principales entre eux :
1. Généralement, l'en-tête des fichiers de projet utilise le mot-clé programme, tandis que l'en-tête des fichiers de projet DLL utilise le mot-clé bibliothèque. Différents mots-clés indiquent au compilateur de générer différents fichiers exécutables. Le mot-clé program est utilisé pour générer un fichier .exe et le mot-clé library est utilisé pour générer un fichier .dll ;
2. Si la DLL souhaite exporter des fonctions ou des procédures pour les utiliser par d'autres applications, ces fonctions ou procédures doivent être répertoriées dans la clause d'exportation. Ces fonctions ou procédures elles-mêmes doivent être compilées à l'aide de la directive de compilation d'exportation.
Sélectionnez le nouvel élément... dans le fichier du menu principal Delphi, double-cliquez sur l'icône DLL dans la fenêtre contextuelle et le cadre du module source DLL sera automatiquement donné, comme suit :
Projet de bibliothèque1 ;
{...annotation...}
utilise
SysUtils,Classes ;
commencer
fin.
Ensuite, vous pouvez ajouter les définitions des procédures et des fonctions que vous souhaitez implémenter dans la DLL entre USES et start, et utiliser export et exports pour les exporter afin que d'autres modules puissent les référencer. Ajoutez du code d'initialisation entre le début et la fin. est utilisé pour initialiser les variables DLL. Il est à noter que même s'il n'y a pas de code d'initialisation, le début et la fin ne peuvent pas être omis, comme dans l'exemple suivant :
bibliothèqueminmax ;
functionMin(X,Y:Integer):Integer;export;
commencer
ifX<YthenMin:=XelseMin:=Y;
fin;
functionMax(X,Y:Integer):Integer;export;
commencer
siX>YthenMax:=XelseMax:=Y;
fin;
exportations
Minindex1,
Maxindex2 ;
commencer
fin.
Après compilation et enregistrement sous minmax.DLL, un fichier de bibliothèque DLL est formé.
Accès à trois bibliothèques de DLL
Il existe deux manières d'accéder à la bibliothèque DLL, l'une par référence statique et l'autre par référence dynamique.
Le chargement d'une DLL à l'aide d'une méthode de référence statique nécessite deux choses : créer une unité d'entrée pour la bibliothèque DLL et utiliser USES pour connecter l'unité d'entrée au module de programme qui utilise les fonctions DLL. La seule différence entre l'unité d'entrée créée pour la bibliothèque DLL et l'unité ordinaire est que les procédures et fonctions déclarées à son interface ne donnent pas le véritable code d'implémentation dans sa partie implémentation. Au lieu de cela, le mot clé external est utilisé pour déclarer les procédures et. fonctions. Les détails d’implémentation sont délégués à des modules DLL externes.
La syntaxe d'utilisation de la commande externe est la suivante :
procédure/fonction nom de la procédure/fonction ; nom du module externalDLL ;
Ce qui suit est le fichier source de l'unité d'entrée testdll.pas écrit pour la bibliothèque minmax.DLL créée ci-dessus, nous pouvons voir quelques différences entre l'unité d'entrée et l'unité générale. Le code est le suivant :
unittestdll;
interface
utilise
fonctionMin(X,Y:Integer):Integer;
fonctionMax(X,Y:Integer):Integer;
mise en œuvre
functionMin;externe'minmax.DLL';
functionMax;externe'minmax.DLL';
fin.
Si une application souhaite appeler une fonction dans minmax.DLL, il lui suffit d'ajouter l'unité testdll à son instruction using.
Le chargement dynamique d'une DLL nécessite trois fonctions API de Windows. Loadlibrary, Freelibrary et GetprocAddress. La fonction loadlibrary permet de charger la bibliothèque DLL. Son format d'appel est le suivant :
functionloadlobrary (DLLfileName: Pchar): THandle :
Lorsqu'une bibliothèque DLL n'est plus nécessaire, la fonction FreeLibrary doit être appelée pour la libérer afin de libérer de précieuses ressources mémoire. Le format d'appel est le suivant :
procédureFreeLibrary (Libmodule: THandle)
Libmodule est le handle de bibliothèque DLL obtenu par l’appel LoadLibrary. Dans le segment de programme entre le chargement d'une bibliothèque DLL avec la fonction loadlobrary et l'appel de FreeLibrary pour libérer la bibliothèque DLL, vous pouvez utiliser les procédures et fonctions de la bibliothèque DLL. La méthode d'utilisation spécifique est la suivante : utilisez la fonction GetprocAddress pour obtenir l'adresse de. la fonction dans la bibliothèque DLL. Transmettez-la à une variable de fonction dans le programme, puis utilisez la variable pour appeler la fonction DLL. La fonction GetprocAddress est déclarée comme suit :
functionGetprocAddress(Libmodule:THandle:procname:pchar):TFarProc:
Comme le montre l'exemple suivant :
taper
TTimeRec=enregistrement
Deuxième : entier ;
Minute : entier ;
Heure : entier ;
fin;
TGetTime=procédure(varTime:TTimeRec);
THandle=Entier ;
var
Heure : TTimeRec ;
Poignée : Poignée ;
GetTime:TGetTime;
...
commencer
Handle:=LoadLibrary('DATETIME.DLL');
ifHandle<>0alors
commencer
@GetTime:=GetProcAddress(Handle,'GetTime');
si @ GetTime <> nul alors
commencer
GetTime(Heure);
avecTimedo
WriteLn('Thetimeis',Heure,':',Minute,':',Second);
fin;
Bibliothèque gratuite (poignée);
fin;
fin;
Lors de l'appel de la bibliothèque de liens dynamiques, vous devez noter que la bibliothèque de liens dynamiques requise doit se trouver dans le même répertoire que l'application ou dans le répertoire WindowsSystem.
Les bibliothèques de liens dynamiques sont un moyen important d'organiser les programmes sous Windows. L'utilisation de bibliothèques de liens dynamiques peut grandement protéger le travail effectué par les utilisateurs dans différents outils de développement et à différentes périodes et améliorer l'efficacité de la programmation.