Bibliothèques partagées pour macOS

De RAD Studio
Aller à : navigation, rechercher

Remonter à Développement d'applications macOS

Partage d'une bibliothèque avec les applications macOS

Lors du développement d'une bibliothèque multi-périphérique partagée dans Delphi, vous devez observer certaines exigences spécifiques à la plate-forme. En particulier, pour les fonctions dont vous vous attendez à ce qu'elles soient chargées et appelées dynamiquement dans les bibliothèques ciblant macOS, vous devez effectuer les opérations suivantes :

  • Commencer les noms des fonctions chargées dynamiquement par un caractère de soulignement ('_').
  • Déplacer l'instruction "exports" du fichier .dpr vers le fichier .pas.

Ces deux recommandations sont décrites plus loin dans cette rubrique.

La version macOS de chaque fonction chargée dynamiquement requiert un caractère de soulignement ('_').

Observez donc les conventions de nom pour la plate-forme cible macOS qui nécessitent un caractère de soulignement ('_') de début dans les noms des fonctions qui seront exportées dans OS X.

Le caractère de soulignement de début est nécessaire pour les applications macOS car la fonction dlsym() de la bibliothèque standard, plus ou moins équivalente à GetProcAddress() dans WinAPI, ajoute un caractère de soulignement au début des noms des fonctions accédées dynamiquement. La bibliothèque est créée comme prévu et est liée statiquement à la compilation, mais quand les fonctions sont appelées dynamiquement au sein d'un programme, elles ne sont pas accessibles à moins qu'elles ne possèdent ce caractère de soulignement au début de leur nom.

Instruction exports non acceptée dans les fichiers .dpr

Pour les bibliothèques qui ciblent macOS, déplacez les instructions "exports" adéquates du fichier .dpr utilisé pour la bibliothèque vers les fichiers .pas définissant les fonctions exportées.

Pour de plus amples informations, voir Ecriture de bibliothèques à chargement dynamique et Fichiers de définition de module.

Exemple de code

Par exemple, l'unité suivante a été conçue pour exporter une fonction avec des noms de fonctions spécifiques à la plate-forme :

  • Windows : TestProc()
  • macOS : _TestProc()
 unit uTestLib;
 
 interface
 
 {$IFDEF MACOS}
 function _TestProc(var I: Integer): Integer; cdecl;
 {$ELSE}
 function TestProc(var I: Integer): Integer; cdecl;
 {$ENDIF}
 
 exports 
 {$IFDEF MACOS}
   _TestProc;
 {$ELSE}
   TestProc;
 {$ENDIF}
 
 implementation
 {$IFDEF MACOS}
 function _TestProc(var I: Integer): Integer; cdecl; export;
 {$ELSE}
 function TestProc(var I: Integer): Integer; cdecl; export;
 {$ENDIF}
 begin
   Result := I;
 end;
 end.

La fonction est référencée dans macOS avec :

  • System.SysUtils.GetProcAddress()
  • Posix.Dlfcn.dlsym()

Ici, le caractère de soulignement ('_') de début n'est pas utilisé, car macOS suppose que toutes les fonctions chargées dynamiquement ont un caractère de soulignement de début et l'ajoute automatiquement au nom.

Remarque : Cette exigence affecte seulement les fonctions chargées dynamiquement et pas celles qui sont liées statiquement avec la directive "external" appliquée à leurs déclarations dans le source. Les fonctions liées statiquement depuis bibliothèques peuvent aussi avoir un caractère de soulignement de début dans leurs noms et c'est souvent le cas sur macOS, mais ce n'est pas nécessaire étant donné que ce sont des fonctions chargées dynamiquement.

Sachez aussi que, pour les bibliothèques ciblant macOS, la clause "exports" n'est pas reconnue si elle est placée dans le fichier source de la bibliothèque principale, c'est-à-dire le fichier .dpr de la bibliothèque. La clause "exports" des fonctions exportées doit apparaître dans un fichier unité, comme illustré dans l'exemple ci-dessus.

Autres considérations

Construire votre bibliothèque avec des packages d'exécution

La bibliothèque (DLL) et l'application doivent être construites avec des packages d'exécution. Autrement, chacune a sa propre copie des objets globaux communs, tels que Platform et Application.

Appeler LoadLibrary

LoadLibrary doit être appelée après le démarrage de l'application. Le chargement de la DLL lors de l'initialisation de l'unité ne fonctionne pas.

Voir aussi