Bibliothèques et packages (Delphi)

De RAD Studio
Aller à : navigation, rechercher

Remonter à Bibliothèques et packages - Index


Une bibliothèque à chargement dynamique est une bibliothèque de liaison dynamique (DLL) sur Windows, ou une bibliothèque DYLIB sur Mac. C'est une collection de routines, pouvant être appelées par des applications ou par d'autres DLLs ou objets partagés. Comme les unités, les bibliothèques à chargement dynamique contiennent des ressources ou du code partagés. Mais ce type de bibliothèque est un exécutable compilé séparément qui est lié, à l'exécution, aux programmes l'utilisant.

Les programmes Delphi peuvent appeler des DLLs et des assemblages écrits dans d'autres langages, et les applications écrites dans d'autres langages peuvent appeler des DLLs ou des assemblages écrits en Delphi.

Appel de bibliothèques à chargement dynamique

Vous pouvez appeler les routines du système d'exploitation directement, mais elles ne sont liées à votre application qu'à l'exécution. Cela signifie que la bibliothèque n'a pas besoin d'être présente lors de la compilation de votre programme. En outre, il n'y a pas de validation à la compilation des tentatives d'importation d'une routine.

Avant de pouvoir appeler les routines définies dans une DLL ou un assemblage, il faut les importer. Cela peut se faire de deux manières : en déclarant une procédure ou une fonction externe ou par des appels directs au système d'exploitation. Quelle que soit la méthode utilisée, les routines ne sont liées à votre application qu'à l'exécution.

Delphi ne supporte pas l'importation des variables depuis les DLLs ou les assemblages.

Chargement statique

La manière la plus simple d'importer une procédure ou une fonction est de la déclarer en utilisant la directive external. Par exemple :

 procedure DoSomething; external 'MYLIB.DLL';

Si vous incluez cette déclaration dans un programme, MYLIB.DLL est chargée une seule fois, au démarrage du programme. Durant toute l'exécution du programme, l'identificateur DoSomething désigne toujours le même point d'entrée dans la même bibliothèque partagée.

La déclaration des routines importées peut être placée directement dans le programme ou l'unité où elles sont appelées. Pour simplifier la maintenance, vous pouvez aussi rassembler des déclarations external dans une "unité d'importation" distincte qui contient aussi les constantes et les types nécessaires pour l'interfaçage avec la bibliothèque. D'autres modules utilisant l'unité d'importation peuvent appeler toutes les routines qui y sont déclarées.

Chargement différé

La directive delayed peut être utilisée pour décorer une routine externe afin de différer le chargement de la bibliothèque contenant la routine. Le chargement réel se produit quand la routine est appelée pour la première fois. L'exemple suivant illustre l'utilisation de la directive delayed :

 function GetSomething: Integer; external 'somelibrary.dll' delayed;

Dans l'exemple ci-dessus, la routine GetSomething est importée depuis la bibiothèque somelibrary.dll. La directive delayed garantit que somelibrary.dll n'est pas statiquement lié à l'application, mais plutôt dynamiquement.

La directive delayed est utile dans le cas où les routines importées n'existent pas sur le système d'exploitation cible sur lequel l'application est exécutée. Les routines importées statiquement nécessitent que le système d'exploitation trouve et charge la bibliothèque au démarrage de l'application. Si la routine n'est pas trouvée dans la bibliothèque chargée, ou si la bibliothèque n'existe pas, le système d'exploitation interrompt l'exécution de l'application. L'utilisation de la directive delayed vous permet de vérifier, à l'exécution, si le système d'exploitation supporte les APIs requises, seulement quand vous pouvez appeler les routines importées.

Une autre utilisation potentielle de la directive delayed est associée à l'encombrement mémoire de l'application : la décoration des routines les moins utilisées, car delayed peut diminuer l'encombrement mémoire de l'application, puisque les bibliothèques sont chargées seulement quand c'est nécessaire. L'utilisation abusive de delayed peut endommager les performances en vitesse du programme (perçues par l'utilisateur final).

Remarque : Une tentative d'appel d'une routine différée qui ne peut être résolue provoque une erreur d'exécution (ou une exception, si l'unité SysUtils est chargée).

Afin d'optimiser le processus de chargement différé utilisé par la bibliothèque d'exécution RTL de Delphi, vous pouvez recenser des procédures de hook pour surveiller et modifier son comportement. Pour accomplir cela, utilisez SetDliNotifyHook2 et SetDliFailureHook2, déclarés dans l'unité SysInit. Voir aussi l'exemple de code DelayedLoading (Delphi).

Chargement dynamique (Windows seulement)

Vous pouvez accéder aux routines d'une bibliothèque via des appels directs aux APIs Windows, notamment LoadLibrary, FreeLibrary et GetProcAddress. Ces fonctions sont déclarées dans Windows.pas. Dans ce cas, utilisez des variables de type procédural pour référencer les routines importées.

Par exemple :

 uses Windows, ...;
  
  type
    TTimeRec = record
      Second: Integer;
      Minute: Integer;
      Hour: Integer;
    end;
  
    TGetTime = procedure(var Time: TTimeRec);
    THandle = Integer;
  
    var
      Time: TTimeRec;
      Handle: THandle;
      GetTime: TGetTime;
  	.
  	.
  	.
    begin
      Handle := LoadLibrary('libraryname');
      if Handle <> 0 then
      begin
       @GetTime := GetProcAddress(Handle, 'GetTime');
       if @GetTime <> nil then
    	begin
     	  GetTime(Time);
      	    with Time do
       	      Writeln('The time is ', Hour, ':', Minute, ':', Second);
           end;
           FreeLibrary(Handle);
         end;
       end;

Quand vous importez ainsi des routines, la bibliothèque n'est pas chargée avant l'exécution du code contenant l'appel de LoadLibrary. La bibliothèque est déchargée ultérieurement par un appel à FreeLibrary. Cela vous permet de conserver de la mémoire et d'exécuter votre programme même si certaines bibliothèques utilisées sont absentes.

Voir aussi