Section courante

A propos

Section administrative du site

 Langage  Installation  Elément  Tutoriel  Programmation  Bibliothèque  Cadre d'application  API  GUI  Projet  Composante  IDE  Outils  Annexe  Aide 
ABAP/4
Ada
Assembleur
Assembly & bytecode
ASP (Active Server Pages)
Basic
C
C++
C# (C Sharp)
Cobol
ColdFusion
Fortran
HTML
Java
JavaScript
LISP
Logo
LotusScript
Oberon
Pascal
Perl
PHP
PL/1
Prolog
Python
Rebol
REXX
Ruby
SAS
NoSQL
SQL
Swift
X++ (Axapta)
GNAT
SMALLAda
VHDL
Assembleur 370
Assembleur 1802
Assembleur 4004
Assembleur 6502
Assembleur 6800
Assembleur 68000
Assembleur 8080 et 8085
Assembleur 8089
Assembleur 80x86
Assembleur AGC4
Assembleur ARM
Assembleur DPS 8000
Assembleur i860
Assembleur Itanium
Assembleur MIPS
Assembleur PDP-11
Assembleur PowerPC
Assembleur RISC-V
Assembleur SPARC
Assembleur SuperH
Assembleur UNIVAC I
Assembleur VAX
Assembleur Z80
Assembleur Z8000
Assembleur z/Architecture
ASSEMBLER/MONITOR 64
Micol Assembler
GFA Assembler
A86
MASM (Macro Assembler)
TASM (Turbo Assembler)
CIL
Jasmin
LLVM
MSIL
Parrot
P-Code (PCode)
SWEET16
G-Pascal
ASP 1.0
ASP 2.0
ASP 3.0
ASP.NET
ASP.NET Core
ABasiC (Amiga)
Adam SmartBASIC
Altair BASIC
AmigaBASIC (Amiga)
AMOS Basic (Amiga)
Atari Basic (Atari 400, 600 XL, 800, 800XL)
Basic Apple II (Integer BASIC/APPLESOFT)
Basic Commodore 64 (CBM-BASIC)
Basic Commodore 128 (BASIC 7.0)
Basic Commodore VIC-20 (CBM-BASIC 2.0)
Basic Coco 1 (Color Basic)
Basic Coco 2 (Extended Color Basic)
Basic Coco 3 (Extended Color Basic 2.0)
BASICA (PC DOS)
Basic Pro
BBC BASIC
Blitz BASIC (Amiga)
DarkBASIC
Dartmouth BASIC
GFA-Basic (Atari ST/Amiga)
GWBASIC (MS-DOS)
Liberty BASIC
Locomotive BASIC (Amstrad CPC)
MSX-Basic
Omikron Basic (Atari ST)
Oric Extended Basic
Power Basic
Quick Basic/QBasic (MS-DOS)
Sinclair BASIC (ZX80, ZX81, ZX Spectrum)
ST BASIC (Atari ST)
Turbo Basic
Vintage BASIC
VBScript
Visual Basic (VB)
Visual Basic .NET (VB .NET)
Visual Basic pour DOS
Yabasic
BeckerBASIC
SIMONS' BASIC
Basic09 d'OS-9
Disk Extended Color Basic
Basic09 d'OS-9
Disk Extended Color Basic
Access
Excel
Visual Basic pour Windows
Visual Basic .NET pour Windows
C Shell Unix (csh)
C pour Amiga
C pour Atari ST
C pour DOS
C pour Falcon030
C pour GEMDOS (Atari ST)
C pour Linux
C pour PowerTV OS
C pour OS/2
C pour Unix
C pour Windows
Aztec C
CoCo-C
GNU C
HiSoft C
IBM C/2
Introl-C
Lattice C
Microsoft C
MinGW C
MSX-C
Open Watcom C
OS-9 C Compiler
Pure C
Quick C
Turbo C
HiSoft C for Atari ST
HiSoft C for CP/M (Amstrad CPC)
C++ pour OS/2
C++ pour Windows
Borland C++
C++Builder
IBM VisualAge C++
Intel C++
MinGW C++
Open Watcom C++
Symantec C++
Turbo C++
Visual C++
Visual C++ .NET
Watcom C++
Zortech C++
C# (C Sharp) pour Windows
Apple III Cobol
Microsoft Cobol
BlueDragon
Lucee
OpenBD
Railo
Smith Project
Microsoft Fortran
WATFOR-77
CSS
FBML
Open Graph
SVG
XML
XSL/XSLT
LESS
SASS
GCJ (GNU)
JSP
Jython
Visual J++
Node.js
TypeScript
AutoLISP
ACSLogo
LotusScript pour Windows
Amiga Oberon
Oberon .NET
Apple Pascal
Delphi/Kylix/Lazarus
Free Pascal
GNU Pascal
HighSpeed Pascal
IBM Personal Computer Pascal
Lisa Pascal
Maxon Pascal
MPW Pascal
OS-9 Pascal
OSS Personal Pascal
Pascal-86
Pascal du Cray Research
Pascal/VS
Pascal-XT
PURE Pascal
QuickPascal
RemObjets Chrome
Sun Pascal
THINK Pascal
Tiny Pascal (TRS-80)
Turbo Pascal
UCSD Pascal
VAX Pascal
Virtual Pascal
Turbo Pascal for CP/M-80
Turbo Pascal for DOS
Turbo Pascal for Macintosh
Turbo Pascal for Windows
CodeIgniter (Cadre d'application)
Drupal (Projet)
Joomla! (Projet)
Phalanger (PHP .NET)
phpBB (Projet)
Smarty (balise)
Twig (balise)
Symfony (Cadre d'application)
WordPress (Projet)
Zend (Cadre d'application)
PL360
PL/M-80
PL/M-86
Turbo Prolog
CPython
IronPython
Jython
PyPy
AREXX
Regina REXX
JMP
Btrieve
Cassandra
Clipper
CouchDB
dBASE
Hbase
Hypertable
MongoDB
Redis
Access
BigQuery
DB2
H2
Interbase
MySQL
Oracle
PostgreSQL
SAP HANA
SQL Server
Sybase
U-SQL
Installation de Free Pascal
Installation de CodeTyphon Studio
Installation de Lazarus
Installation de Pascal XE
Introduction
Les remarques
Les opérateurs
Les instructions conditionnelles
Les instructions de boucles
Les instructions d'exceptions
Type de données élémentaires
Référence des unités
Référence de mots réservés (mots clefs)
Référence de procédures et fonctions
Référence des directives de compilation
Référence de classes
BASEUNIX
CLASSES
CMEM
CRT
CTHREADS
CWSTRING
GRAPH
MATH
SYSTEM
Référence de procédures et fonctions avec prototype
Les jetons
Les constantes
Directives du compilateur
Utiliser des conditions, des messages et des macros
Utilisation du langage de programmation assembleur
Code généré
Prise en charge d'Intel MMX
Problèmes de code
Problèmes de liaison
Problèmes de mémoire
Chaînes de caractères de ressources
Programmation de processus léger
Optimisations
Programmation de bibliothèques partagées
Utiliser les ressources Windows
Bonjour
Affichage
Astronomie
Biochimie
Électricité
Fichiers
Finance
Géographie
Géométrie
Histoire
Jeux & stratégies
Mathématique
Médicale
Météorologie
Océanographie
Sport
Temps
Tri
Trigonométrie
Validation
«DRAW» du BASIC
Phase lunaire
Calcul du calcium corrigé
Calcul le taux d'alcoolémie
Comparaison de séquence de polypeptides
Tarif d'une piscine pour 1 mois
Texte séquentiel
Liste des fichiers
IPaymt/Interet
NPer
PPaymt/Principal
Distance en Km entre deux longitudes et latitudes
Aire d'un cercle
Aire d'une surface de prisme rectangulaire
Aire d'un triangle
Distance entre deux points
Treillis
Chiffre romain
Pac-Man
Tetris
Tours d'Hanois
Ackermann
Exp
Factoriel
Fibonacci
Log
Nombre premier
Odd
Random
Sqrt
Triangle Pascal
Hauteur utérine
Unité de mesure
Fréquence des vagues
Hockey
Année bissextile
Calendrier
Date de la Pâque
Heure courante
Horloge à aiguille
FirstDayOfMonth
Tri à bulle (Bubble Sort)
Tri Shell Sort
ArcCos
ArcSin
Atn/ATan/ArcTan
Cos
Sin
Courriel
Extension de nom de domaine
Ararat Synapse
CryptoLib4Pascal
FBLib (Firebird Pascal Library)
FCL (Free Component Library)
GraphiX
HashLib4Pascal
INDY (Internet Direct)
LCL (Lazarus Component Library)
QuickLib
QuickLogger
WinGraph
ZeosLib
Daraja (cadre d'application pour Web)
Fano Framework
Free Spider
Horse
Synopse mORMot
tiOPF
CAI NEURAL API
tensorflowforpascal
fpGUI
MOS
Corail
Double Commander
LDAP Admin for Linux
MSDOS-0
Transmission Remote GUI
UNIX-0
Python for Delphi (P4D)
CodeTyphon Studio
Free Pascal IDE
Lazarus
Pascal XE
GNU Debugger (GDB)
Delp
FPCMake
H2Pas
PPDep
PPUDump
PPUMove
PtoP
Références des codes d'erreur
Anatomie d'un fichier unité
Structure de l'arborescence des sources du compilateur et RTL
Limites du compilateur
Modes du compilateur
Utiliser fpcmake
Compilation du compilateur
Compilateur définit lors de la compilation
Préface
Notes légal
Dictionnaire
Recherche

Programmation de bibliothèques partagées

Le Free Pascal prend en charge la création de bibliothèques partagées sur plusieurs systèmes d'exploitation. Le tableau suivant indique quels systèmes d'exploitation prennent en charge la création de bibliothèques partagées :

Systèmes d'exploitation Extension de la bibliothèque Préfixe de bibliothèque
Linux .so lib
Windows .dll Aucun
BeOS .so lib
FreeBSD .so lib
NetBSD .so lib

La colonne de préfixe de bibliothèque indique comment les noms des bibliothèques sont résolus et créés. Par exemple, sous Linux, le nom de la bibliothèque aura toujours le préfixe lib lors de sa création. Donc si vous créez une bibliothèque appelée mylib, sous Linux, cela donnera le libmylib.so. De plus, lors de l'importation de routines depuis des bibliothèques partagées, il n'est pas nécessaire de donner le préfixe de la bibliothèque ou l'extension du nom de fichier.

Dans les sections suivantes, nous expliquons comment créer une bibliothèque et comment utiliser ces bibliothèques dans des programmes.

Création d'une bibliothèque

La création de bibliothèques est prise en charge dans n'importe quel mode du compilateur Free Pascal, mais il se peut que les paramètres ou les valeurs de retour diffèrent si la bibliothèque est compilée dans 2 modes différents. Par exemple. si votre fonction attend un paramètre Integer, alors la bibliothèque attendra différentes tailles entières si vous la compilez en mode Delphi ou en mode TP.

Une bibliothèque peut être créée comme un programme, seulement elle utilise le mot-clef library et elle possède une section d'exportation. La liste suivante présente une bibliothèque simple (progex/subs.pp) :

  1. Library Subs;
  2.  
  3. Function SubStr(CString:PChar;FromPos,ToPos:LongInt):PChar; cdecl;
  4. Var
  5.  _Length:Integer;
  6. Begin
  7.  _Length:=StrLen(CString);
  8.  SubStr:=CString+_Length;
  9.  If(FromPos>0)and(ToPos>=FromPos)Then Begin
  10.   If _Length>=FromPos Then SubStr:=CString+FromPos;
  11.   If _Length>ToPos Then CString[ToPos+1]:=#0;
  12.  End;
  13. End;
  14.  
  15. Exports
  16.  SubStr;
  17.  
  18. END.

La fonction SubStr n'a pas besoin d'être déclarée dans le fichier bibliothèque lui-même. Il peut également être déclaré dans la section interface d'une unité utilisée par la bibliothèque.

La compilation de cette source entraînera la création d'une bibliothèque appelée libsubs.dylib sur MacOS, libsubs.so sur d'autres systèmes Unix, ou subs.dll sur Windows ou OS/2. Le compilateur prendra en charge toute liaison supplémentaire nécessaire pour créer une bibliothèque partagée.

La bibliothèque exporte une fonction : SubStr. L'affaire est importante. La casse telle qu'elle apparaît dans la clause Exports est utilisée pour exporter la fonction.

Si vous souhaitez que votre bibliothèque soit appelée à partir de programmes compilés avec d'autres compilateurs, il est important de spécifier la convention d'appel correcte pour les fonctions exportées. Étant donné que les programmes générés par d'autres compilateurs ne connaissent pas les conventions d'appel de Free Pascal, vos fonctions seraient appelées de manière incorrecte, ce qui entraînerait une pile corrompue.

Sous Windows, la plupart des bibliothèques utilisent la convention stdcall, il peut donc être préférable d'utiliser celle-là si votre bibliothèque doit être utilisée sur les systèmes Windows. Sur la plupart des systèmes Unix, la convention d'appel C est utilisée, donc le modificateur cdecl doit être utilisé dans ce cas.

Utiliser une bibliothèque dans un programme Pascal

Pour utiliser une fonction résidant dans une bibliothèque, il suffit de déclarer la fonction telle qu'elle existe dans la bibliothèque comme fonction externe, avec les paramètres et le type de retour corrects. La convention d'appel utilisée par la fonction doit également être déclarée correctement. Le compilateur liera ensuite la bibliothèque comme spécifié dans l'instruction externe à votre programme.

Par exemple, pour utiliser la bibliothèque telle que définie ci-dessus depuis un programme Pascal, vous pouvez utiliser le programme Pascal suivant, nommé progex/psubs.pp, (sauf sur les MacOS) :

  1. Program TestSubs;
  2.  
  3. Uses Strings;
  4.  
  5. Function SubStr(Const CString:PChar;FromPos,ToPos:LongInt):PChar;cdecl;External 'subs';
  6.  
  7. Var
  8.  S:PChar;
  9.  FromPos,ToPos:Integer;
  10.  
  11. BEGIN
  12.  S:=StrNew('TestMe');
  13.  FromPos:=2;
  14.  ToPos:=3;
  15.  WriteLn(SubStr(S,FromPos,ToPos));
  16. END.

Comme le montre l'exemple, vous devez déclarer la fonction comme externe, suivie du nom de la bibliothèque. Sur Mac, vous devez également ajouter la directive {$linklib }, comme dans l'exemple suivant (progex/psubsm.pp) :

  1. Program TestSubs;
  2.  
  3. Uses Strings;
  4.  
  5. Function SubStr(Const CString:PChar;FromPos,ToPos:LongInt):PChar;cdecl; External 'subs';
  6.  
  7. Var
  8.  s:PChar;
  9.  FromPos,ToPos:Integer;
  10.  
  11. BEGIN
  12.  S:=StrNew('TestMe');
  13.  FromPos:=2;
  14.  ToPos:=3;
  15.  WriteLn(SubStr(s,FromPos,ToPos));
  16. END.

Ici aussi, il est nécessaire de spécifier la convention d'appel correcte (elle doit toujours correspondre à la convention utilisée par la fonction dans la bibliothèque), et d'utiliser la casse correcte pour votre déclaration. Notez également que l'importation de la bibliothèque n'a pas spécifié l'extension du nom de fichier et que le préfixe lib n'a pas été ajouté.

Ce programme peut être compilé sans aucun commutateur de commande supplémentaire et devrait fonctionner comme ça, à condition que la bibliothèque soit placée là où le système peut la trouver. Par exemple, sous Linux, il s'agit de /usr/lib ou de tout répertoire répertorié dans le fichier /etc/ld.so.conf. Sous Windows, il peut s'agir du répertoire du programme, du répertoire système Windows ou de tout répertoire mentionné dans le PATH.

Utiliser la bibliothèque de cette manière relie la bibliothèque à votre programme au moment de la compilation. Cela signifie que :

Ou il se peut simplement que vous ne connaissiez pas le nom de la fonction à appeler, vous connaissez simplement les arguments qu'elle attend.

Il est donc également possible de charger la bibliothèque au moment de l'exécution, d'entreposer l'adresse de la fonction dans une variable procédurale et d'utiliser cette variable procédurale pour accéder à la fonction dans la bibliothèque. Le dynlibs fournit une API multiplateforme pour charger une bibliothèque et obtenir les points d'entrée des fonctions dans la bibliothèque.

L'exemple suivant, nommé progex/plsubs.pp, illustre cette technique :

  1. Program TestSubs;
  2.  
  3. Uses DynLibs;
  4.  
  5. Type
  6.  TSubStrFunc=Function(Const CString:PChar; FromPos,ToPos:LongInt):PChar; cdecl;
  7.  
  8. Const
  9.  BaseLibName='libsubs.';
  10. {$IFDEF WINDOWS}
  11.  libext='dll';
  12. {$ELSE}
  13.  {$IFDEF MACOS}
  14.   libext='dylib';
  15.  {$ELSE}
  16.   libext='so';
  17.  {$ENDIF}
  18. {$ENDIF}
  19.  
  20. Var
  21.  S:PChar ;
  22.  FromPos,ToPos:Integer;
  23.  Lib:TLibHandle;
  24.  SubStr:TSubStrFunc;
  25.  
  26. BEGIN
  27.  S:='Test';
  28.  FromPos:=2;
  29.  ToPos:=3;
  30.  Lib:=LoadLibrary('libsubs.so');
  31.  Pointer(Substr):=GetProcAddress(lib,'SubStr');
  32.  WriteLn(SubStr(s,FromPos,ToPos));
  33.  UnloadLibrary(Lib);
  34. END.

Comme dans le cas des liaisons à la compilation, l'élément crucial de ce code source est la déclaration du type TSubStrFunc. Il doit correspondre à la déclaration de la fonction que vous essayez d'utiliser.

Le fait de ne pas spécifier une définition correcte entraînera une pile défectueuse ou, pire encore, pourrait provoquer le crash de votre programme en raison d'une violation d'accès.

Utiliser une bibliothèque Pascal à partir d'un programme C

Remarque : Les exemples de cette section supposent un système Linux ; Des commandes similaires à celles ci-dessous existent cependant pour d'autres systèmes d'exploitation.

Vous pouvez également appeler une bibliothèque générée par Free Pascal depuis un programme C (celui-ci est nommé progex/ctest.c) :

  1. #include <string.h>
  2. #include <stdio.h>
  3.  
  4. extern char * SubStr(const char *, int, int);
  5.  
  6. int main() {
  7.  char * s;
  8.  int FromPos,ToPos;
  9.  s=strdup(" Test ");
  10.  FromPos=2;
  11.  ToPos=3;
  12.  printf("Result from SubStr : '%s '\n",SubStr(s,FromPos,ToPos));
  13.  return 0;
  14. }

Pour compiler cet exemple, la commande suivante peut être utilisée :

gcc -o ctest ctest.c -lsubs

à condition que le code soit dans ctest.c.

La bibliothèque peut également être chargée dynamiquement à partir de C, comme le montre l'exemple suivant (progex/ctest2.c) :

  1. #include <dlfcn.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4.  
  5. int main() {
  6.  void * lib;
  7.  char *s;
  8.  int FromPos,ToPos;
  9.  char *(*SubStr) (const char *, int, int);
  10.  lib=dlopen("./libsubs.so",RTLD_LAZY);
  11.  SubStr = dlsym(lib,"SUBSTR");
  12.  s=strdup( " Test " );
  13.  FromPos=2;
  14.  ToPos=3;
  15.  printf("Résultat de SubStr : '%s '\n",(*SubStr) (s,FromPos,ToPos));
  16.  dlclose(lib);
  17.  return 0;
  18. }

Cela peut être compilé à l'aide de la commande suivante :

gcc -o ctest2 ctest2.c -ldl

Le -ldl indique à gcc que le programme a besoin de la bibliothèque libdl.so pour charger les bibliothèques dynamiques.

Quelques problèmes Windows

Par défaut, Free Pascal (en fait, l'éditeur de liens utilisé par Free Pascal) crée des bibliothèques n'étant pas déplaçables. Cela signifie qu'ils doivent être chargés à une adresse fixe en mémoire : cette adresse est appelée adresse ImageBase. Si deux bibliothèques générées par Free Pascal sont chargées par un programme, il y aura un conflit, car la première bibliothèque occupe déjà l'emplacement mémoire où la deuxième bibliothèque doit être chargée.

Il existe 2 commutateurs dans Free Pascal contrôlant la génération des bibliothèques partagées sous Windows :

La première option est préférable, car un programme peut charger de nombreuses bibliothèques présentes sur le système et celles-ci peuvent déjà utiliser l'adresse ImageBase. La deuxième option est plus rapide, car aucun déplacement n'est nécessaire si l'adresse ImageBase n'est pas encore utilisée.



PARTAGER CETTE PAGE SUR
Dernière mise à jour : Dimanche, le 27 août 2023