Provided by: manpages-fr_1.67.0-1_all bug

NOM

       dladdr,   dlclose,  dlerror,  dlopen,  dlsym,  dlvsym  -  Interface  de
       programmation pour le chargeur de bibliothèques dynamiques.

SYNOPSIS

       #include <dlfcn.h>

       void *dlopen(const char *filename, int flag);

       char *dlerror(void);

       void *dlsym(void *handle, const char *symbol);

       int dlclose(void *handle);

DESCRIPTION

       Les  quatres  fonctions   dlopen(),   dlsym(),   dlclose(),   dlerror()
       implémentent  l’interface pour le chargeur de bibliothèques dynamiques.

   dlerror
       La fonction dlerror() renvoie une chaîne de caractères,  compréhensible
       par  l’homme,  décrivant  la  dernière  erreur  survenue dans n’importe
       laquelle des routines « dl »  (dlopen,  dlsym  ou  dlclose)  depuis  le
       dernier  appel  à  dlerror().  Elle renvoie NULL si aucune erreur n’est
       survenue depuis l’initialisation ou depuis son dernier appel.

   dlopen
       La fonction dlopen() charge la bibliothèque dynamique depuis le fichier
       dont  le  nom  est  fourni  dans  la  chaîne  filename (terminée par un
       caractère nul) et renvoie un descripteur opaque  (handle)  représentant
       la  bibliothèque  dynamique.   Si  l’argument  filename est un pointeur
       NULL, le descripteur renvoyé correspond  au  programme  principal.   Si
       filename contient une barre oblique (« / »), il est interprété comme un
       chemin (relatif ou absolu).  Autrement, le chargeur  dynamique  cherche
       la  bibliothèque  de  la  façon  suivante  (voir  ld.so(8) pour plus de
       détails) :

       o      (ELF seulement) si  le  fichier  exécutable  pour  le  programme
              appelant   contient  la  balise  DT_RPATH  mais  pas  la  balise
              DT_RUNPATH, les  répertoires  listés  dans  la  balise  DT_RPATH
              seront parcourus.

       o      Si  la  variable  d’environnement LD_LIBRARY_PATH est définie et
              contient une liste de répertoires (séparés par  des  deux-points
              « : »),   ces  répertoires  seront  parcourus.  (Par  mesure  de
              sécurité, cette variable est ignorée dans le cas  de  programmes
              set-UID et set-GID.)

       o      (ELF  seulement)  si  le  fichier  exécutable  pour le programme
              appelant contient la balise DT_RUNPATH, les  répertoires  listés
              dans cette balise seront parcourus.

       o      Le fichier cache /etc/ld.so.cache (maintenu par ldconfig(8)) est
              vérifié pour voir  s’il  contient  une  entrée  correspondant  à
              filename.

       o      Les  répertoires  /lib  et  /usr/lib  sont  parcourus  (dans cet
              ordre).

       Si  la  bibliothèque  a  des  dépendances  sur  d’autres  bibliothèques
       partagées,  celles-ci  seront  automatiquement chargées par le chargeur
       dynamique, en utilisant les  mêmes  règles.  (Le  processus  peut  être
       récursif  si  ces  bibliothèques  ont, à leur tour, des dépendances, et
       ainsi de suite.)

       La valeur de flag peut être soit  RTLD_LAZY,  soit  RTLD_NOW.   Lorsque
       RTLD_NOW  est spécifiée, ou que la variable d’environnement LD_BIND_NOW
       est positionnée avec une chaîne non vide, tous les symboles non définis
       sont  résolus  avant  le  retour de dlopen().  Si cela ne peut pas être
       fait, une erreur est renvoyée.  Autrement, la liaison  est  fainéante :
       les symboles sont résolus la première fois lorsqu’on en a besoin.

       En  option, on peut ajouter (avec un OU binaire) l’attribut RTLD_GLOBAL
       rendant les symboles externes de la bibliothèque disponibles  pour  les
       bibliothèques chargées ultérieurement. (Le contraire de RTLD_GLOBAL est
       RTLD_LOCAL.  C’est la valeur par défaut.)

       Si l’argument filename est un pointeur  NULL,  le  descripteur  renvoyé
       correspond  au  programme principal.  Lorsqu’il est passé à dlsym(), ce
       descripteur provoque  la  recherche  d’un  symbole  dans  le  programme
       principal,  puis  dans  toutes  les bibliothèques partagées chargées au
       démarrage du programme, puis dans toutes  les  bibliothèques  partagées
       chargées par dlopen() avec l’attribut RTLD_GLOBAL.

       Les  références  externes de la bibliothèque sont résolues en utilisant
       les bibliothèques mentionnées dans sa liste de dépendances,  et  toutes
       les   autres  bibliothèques  éventuellement  ouvertes  auparavant  avec
       l’attribut RTLD_GLOBAL.  Si l’édition des liens de l’exécutable  a  été
       faite   avec   l’option   « -rdynamic »   (ou,   de  manière  synonyme,
       « --export-dynamic »), alors  ses  symboles  globaux  seront  également
       employés  pour  résoudre  les  références  de  la  bibliothèque chargée
       dynamiquement.

       Si la même bibliothèque est chargée une nouvelle fois avec dlopen(), le
       même  descripteur  sera renvoyé. Un compte du nombre de chargements est
       toutefois conservé afin d’éviter de la décharger avant que la  fonction
       dlclose()  n’ait  été  appelée autant de fois que dlopen() a réussi. La
       routine _init, si elle existe, est appelée  une  seule  fois.  Mais  un
       appel  postérieur  avec  RTLD_NOW peut forcer la résolution de symboles
       pour une bibliothèque précédemment chargée avec RTLD_LAZY.

       Si dlopen() échoue pour une raison quelconque, elle renvoie NULL.

   dlsym
       La fonction dlsym() prend  un  descripteur  de  bibliothèque  dynamique
       renvoyée  par  dlopen()  et  un nom de symbole terminé par un caractère
       nul, et renvoie l’adresse où ce symbole a été  chargé.  Si  le  symbole
       n’est  pas  trouvé,  soit  dans  la  bibliothèque  spécifiée, soit dans
       n’importe quelle  bibliothèque  chargée  automatiquement  par  dlopen()
       lorsque  cette  bibliothèque  a  été chargée, dlsym() renvoie NULL. (La
       recherche effectuée par  dlsym()  est  en  largeur  d’abord  à  travers
       l’arbre  des  dépendances  de  ces  bibliothèques.)  Le symbole pouvant
       légitimement avoir la valeur NULL (la valeur NULL renvoyée par  dlsym()
       n’indique  pas nécessairement une erreur), la bonne manière de vérifier
       si une erreur s’est produite est d’appeler dlerror() pour effacer toute
       ancienne  condition  d’erreur,  puis  d’appeler  dlsym() et appeler une
       nouvelle fois dlerror() en sauvegardant sa valeur de  retour  dans  une
       variable et vérifier si la valeur sauvegardée n’est pas NULL.

       Il  y  a deux pseudo-descripteurs spéciaux : RTLD_DEFAULT et RTLD_NEXT.
       Le premier recherche  la  première  occurrence  du  symbole  désiré  en
       utilisant  l’ordre de recherche des bibliothèques par défaut. Le second
       recherche  l’occurrence  suivante  d’une  fonction  à  partir   de   la
       bibliothèque  en cours.  Ceci permet de fournir un encadrement pour une
       fonction se trouvant dans une autre bibliothèque partagée.

   dlclose
       La fonction  dlclose()  décrémente  le  nombre  de  références  sur  la
       bibliothèque  dynamique  dont  le descripteur est handle.  Si ce nombre
       descend à zéro et si aucune autre bibliothèque n’emploie  des  symboles
       exportés par celle-ci, elle est déchargée.

       La  fonction  dlclose()  renvoie  0  si elle réussit, et une valeur non
       nulle si une erreur est survenue.

   Les symboles obsolètes _init et _fini
       L’éditeur de liens reconnait les symboles spéciaux _init et _fini.   Si
       une  bibliothèque  dynamique exporte une routine nommée _init, son code
       est exécuté après le chargement, avant le retour de  dlopen().   Si  la
       bibliothèque  exporte  une routine nommée _fini, elle est appelée juste
       avant le déchargement.  Au cas où vous voudriez éviter le lien avec les
       fichiers  de  démarrage  du  système, vous pouvez préciser le paramètre
       « -nostartfiles » sur la ligne de commande de gcc.

       L’utilisation de ces routines ou des  options  gcc  -nostartupfiles  ou
       -nostdlib  n’est  pas  recommandée. Il peut en résulter un comportement
       non désiré tant que les routines constructeur/destructeur ne  sont  pas
       exécutées (à moins que des mesures spéciales ne soient prises).

       À  la  place,  les  bibliothèques  devraient  exporter  les routines en
       utilisant  les  fonctions  attributs  __attribute__((constructor))   et
       __attribute__((destructor)).   Voir  les  pages  info  de gcc pour plus
       d’information sur celles-ci. Les routines constructeur  sont  exécutées
       avant  que  dlopen  revienne et les routines destructeur sont exécutées
       avant que dlclose revienne.

EXTENSIONS GNU

       La GlibC a ajouté deux fonctions, qui ne sont pas décrites  par  POSIX,
       dont les prototypes sont :

       #define GNU_SOURCE
       #include <dlfcn.h>

       int dladdr(void *addr, Dl_info *info);

       void *dlvsym(void *handle, char *symbol, char *version);

       La  fonction  dladdr() prend un pointeur vers une fonction et essaie de
       résoudre le nom et le fichier où  elle  se  trouve.  L’information  est
       stockée dans une structure Dl_info :

       typedef struct {
         const char *dli_fname;/* File name of defining object */
         void *dli_fbase;      /* Load address of that object */
         const char *dli_sname;/* Name of nearest lower symbol */
         void *dli_saddr;      /* Exact value of nearest symbol */
       } Dl_info;

       dladdr()  renvoie  0  en  cas  d’erreur et une valeur non nulle si elle
       réussit.

       La fonction dlvsym() effectue la même chose que dlsym() mais prend  une
       chaîne version comme argument supplémentaire.

EXEMPLE

       Charger la bibliothèque mathématique et afficher le cosinus de 2.0 :
              #include <stdio.h>
              #include <dlfcn.h>

              int main(int argc, char **argv) {
                  void *handle;
                  double (*cosine)(double);
                  char *error;

                  handle = dlopen ("libm.so", RTLD_LAZY);
                  if (!handle) {
                      fprintf (stderr, "%s\n", dlerror());
                      exit(1);
                  }

                  dlerror();    /* Clear any existing error */
                  *(void **) (&cosine) = dlsym(handle, "cos");
                  if ((error = dlerror()) != NULL)  {
                      fprintf (stderr, "%s\n", error);
                      exit(1);
                  }

                  printf ("%f\n", (*cosine)(2.0));
                  dlclose(handle);
                  return 0;
              }

       Supposons  que  le  programme  s’appelle « foo.c », on doit le compiler
       ainsi :

              gcc -rdynamic -o foo foo.c -ldl

       Une bibliothèque (disons bar.c) qui exporte  _init()  et  _fini()  sera
       compilée comme suit :

              gcc -shared -nostartfiles -o bar bar.c

NOTES

       Les  symboles  RTLD_DEFAULT  et  RTLD_NEXT  sont définis dans <dlfcn.h>
       seulement si _GNU_SOURCE a été définie avant l’inclusion.

HISTORIQUE

       L’interface standard dlopen provient de SunOS. Ce système  a  également
       dladdr mais pas dlvsym.

CONFORMITÉ

       POSIX 1003.1-2003 describes dlclose, dlerror, dlopen, dlsym.

VOIR AUSSI

       ld(1), ldd(1), ld.so(8), ldconfig(8), ld.so info pages, gcc info pages,
       ld info pages

TRADUCTION

       Christophe Blaess, 2000-2003.

       Alain Portal, 2005