Provided by: manpages-fr-dev_3.57d1p1-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);

       Effectuez l'édition des liens avec l'option -ldl.

DESCRIPTION

       Les quatre 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 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 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
       (consultez 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  à  l'instant où le programme est démarré, 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  de 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.)

       L'une des deux valeurs suivantes doit être incluse dans flag :

       RTLD_LAZY
              Effectuer des liaisons paresseuses. Résoudre seulement les symboles dont le code qui les référence
              est  exécuté.  Si  le  symbole n'est jamais référencé, alors il n'est jamais résolu. (Les bindings
              paresseux ne sont seulement effectués que pour les références de  fonctions ;  les  références  de
              variables sont toujours immédiatement liées quand la bibliothèque est chargée).

       RTLD_NOW
              Si cette valeur est spécifiée, ou que la variable d'environnement LD_BIND_NOW est définie avec une
              chaîne non vide, tous les symboles non définis de la bibliothèque sont résolus avant le retour  de
              dlopen(). Si cela ne peut pas être fait, une erreur est renvoyée.

       Zéro ou plusieurs des valeurs suivantes peuvent être spécifiées avec un OU binaire dans flag :

       RTLD_GLOBAL
              Les symboles définis par cette bibliothèque seront disponibles pour la résolution des symboles des
              futurs chargements de bibliothèques.

       RTLD_LOCAL
              C'est la réciproque de RTLD_GLOBAL, et le comportement par défaut si aucun drapeau n'est spécifié.
              Les  symboles définis dans cette bibliothèque ne sont pas disponibles pour résoudre les références
              des chargements de bibliothèques futurs.

       RTLD_NODELETE (depuis la glibc 2.2)
              Ne pas décharger la bibliothèque lors de dlclose(). En conséquence, les variables statiques de  la
              bibliothèque  ne  sont  pas  réinitialisées  si  la  bibliothèque  est chargée ultérieurement avec
              dlopen() . Ce drapeau n'est pas spécifié dans POSIX.1-2001.

       RTLD_NOLOAD (depuis la glibc 2.2)
              Ne pas charger la bibliothèque. Ceci peut être utilisé pour tester si la  bibliothèque  n'est  pas
              déjà  chargée  (dlopen()  renvoie  NULL  si  elle  n'est  pas  chargée,  ou  le  descripteur de la
              bibliothèque si elle déjà chargée). Ce  drapeau  peut  aussi  être  utilisé  pour  promouvoir  les
              drapeaux  d'une  bibliothèque  déjà  chargée. Par exemple, une bibliothèque qui a été chargée avec
              RTLD_LOCAL peut être de nouveau ouverte  avec  RTLD_NOLOAD | RTLD_GLOBAL.  Ce  drapeau  n'est  pas
              spécifié dans POSIX.1-2001.

       RTLD_DEEPBIND (depuis la glibc 2.3.4)
              Placer  l'espace  de  recherche  des  symboles  de  cette bibliothèque avant l'espace global. Cela
              signifie qu'une bibliothèque autonome utilisera ses propres symboles de  préférence  aux  symboles
              globaux  de même noms contenus dans les bibliothèques déjà chargées. Ce drapeau n'est pas spécifié
              dans POSIX.1-2001.

       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  le
       drapeau  RTLD_GLOBAL. Si l'édition des liens de l'exécutable a été faite avec l'option « -rdynamic » (ou,
       de manière synonyme, avec « --export-dynamic »), alors les symboles globaux du programme seront également
       utilisés pour résoudre les références d'une 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  des
       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  comme  arguments,  un « descripteur » de bibliothèque dynamique renvoyé par
       dlopen() et un nom de symbole terminé par un caractère nul, et renvoie l'adresse  où  ce  symbole  a  été
       chargé  en  mémoire.  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 d'abord en largeur à 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 pseudodescripteurs 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 une enveloppe 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 d'une bibliothèque dynamique dont le descripteur
       est handle. Si ce nombre atteint 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 en cas d'erreur.

   Les symboles obsolètes _init() et _fini()
       L'éditeur  de liens reconnaît les symboles spéciaux _init et _fini. Si une bibliothèque dynamique exporte
       une routine nommée _init(), alors 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 de lier l'exécutable avec les fichiers  de  démarrage  du  système,  vous  pouvez
       spécifier le paramètre -nostartfiles à la ligne de commande de gcc(1).

       L'utilisation  de  ces  routines  ou des options gcc -nostartfiles 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 attribut
       __attribute__((constructor)) et __attribute__((destructor)). Consultez la documentation de gcc au  format
       Info  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 de la glibc :dladdr() et dlvsym()
       La glibc a ajouté deux fonctions, qui ne sont pas décrites par POSIX, dont les prototypes sont :

       #define _GNU_SOURCE         /* Consultez feature_test_macros(7) */
       #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ù il
       se trouve. L'information est stockée dans une structure Dl_info :

           typedef struct {
               const char *dli_fname; /* Chemin du fichier de l'objet partagé
                                         contenant l'adresse */
               void       *dli_fbase; /* Adresse à laquelle l'objet partagé
                                         est chargé */
               const char *dli_sname; /* Nom du symbole dont la définition
                                         chevauche addr */
               void       *dli_saddr; /* Adresse exacte du symbole dont
                                         le nom est dli_sname */
           } Dl_info;

       Si  aucun symbole correspondant à l'adresse addr ne peut être trouvé, dli_sname et dli_saddr sont définis
       à NULL.

       dladdr() renvoie 0 en cas d'erreur et une valeur non nulle en cas de succès.

       La fonction dlvsym(), fournie par la glibc depuis la version 2.1, effectue la même chose que dlsym() mais
       prend une version sous forme de chaîne comme argument supplémentaire.

CONFORMITÉ

       POSIX.1-2001 décrit dlclose(), dlerror(), dlopen() et dlsym().

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.

       Depuis la glibc 2.2.3, atexit(3) peut être utilisée pour enregistrer un gestionnaire de sortie  qui  sera
       automatiquement appelé quand une bibliothèque sera déchargée.

   Historique
       L'interface standard dlopen provient de SunOS. Ce système possède également dladdr() mais pas dlvsym().

BOGUES

       Quelquefois,  les  pointeurs  de  fonctions  passés  à  dladdr()  peuvent  vous surprendre. Sur certaines
       architectures (notablement i386 et x86_64), dli_fname et dli_fbase peuvent  pointés  sur  l'objet  depuis
       lequel  vous  appelez  dladdr(),  même  si  la  fonction  utilisée  en  paramètre  semble  provenir d'une
       bibliothèque liée dynamiquement.

       Le problème est que le pointeur de fonction ne sera résolu  que  lors  de  la  compilation,  mais  pointe
       simplement vers la section de l'objet original plt (table de procédure d'édition des liens), qui redirige
       l'appel après avoir demandé à l'éditeur de liens dynamique de  résoudre  le  symbole).  Un  contournement
       consiste  à compiler le code pour qu'il soit indépendant de son adressage : dans ce cas le compilateur ne
       peut pas préparer le pointeur à la compilation, et de nos jours, gcc(1) générera  du  code  qui  chargera
       juste l'adresse finale du symbole depuis la table GOT (table d'offset globale) lors de l'exécution, avant
       de la passer à dladdr().

EXEMPLE

       Charger la bibliothèque mathématique et afficher le cosinus de 2,0 :

       #include <stdio.h>
       #include <stdlib.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(EXIT_FAILURE);
           }

           dlerror();    /* Clear any existing error */

           cosine = (double (*)(double)) dlsym(handle, "cos");

           /* D'après le standard ISO C, la conversion de type entre un pointeur
              de fonction et « void * », comme effectuée ci-dessus, produit des
              résultats indéfinis.
              POSIX.1-2003 et POSIX.1-2008 ont admis cet état de fait et proposé
              le contournement ci-dessous :

                  *(void **) (&cosine) = dlsym(handle, "cos");

              Cette conversion (lourde) de type est conforme au standard
              ISO C and évitera tout avertissement du compilateur.

              La révision technique 2013 de POSIX.1-2008 (aussi appelée
              POSIX.1-2013) a amélioré la situation en exigeant que les
              implémentations prennent en charge la conversion du type
              « void * » vers un pointeur de fonction.'
              Cependant, certains compilateurs (par exemple gcc avec
              l'option « -pedantic ) peuvent se plaindre de la conversion
              effectuée dans ce programme. */

           error = dlerror();
           if (error != NULL) {
               fprintf(stderr, "%s\n", error);
               exit(EXIT_FAILURE);
           }

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

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

           gcc -rdynamic -o foo foo.c -ldl

       Une bibliothèque (bar.c dans l'exemple suivant) qui exporte _init() et _fini() sera compilée comme suit :

           gcc -shared -nostartfiles -o bar bar.c

VOIR AUSSI

       ld(1), ldd(1), dl_iterate_phdr(3), rtld-audit(7), ld.so(8), ldconfig(8)

       les pages Info de ld.so, gcc, ld

COLOPHON

       Cette page fait partie de la publication 3.57 du projet man-pages Linux. Une description du projet et des
       instructions     pour     signaler     des     anomalies    peuvent    être    trouvées    à    l'adresse
       http://www.kernel.org/doc/man-pages/.

TRADUCTION

       Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a <http://po4a.alioth.debian.org/> par
       l'équipe de traduction francophone au sein du projet perkamon <http://perkamon.alioth.debian.org/>.

       Christophe       Blaess       <http://www.blaess.fr/christophe/>      (1996-2003),      Alain      Portal
       <http://manpagesfr.free.fr/> (2003-2006). Florentin Duneau  et  l'équipe  francophone  de  traduction  de
       Debian (2006-2009).

       Veuillez  signaler  toute erreur de traduction en écrivant à <debian-l10n-french@lists.debian.org> ou par
       un rapport de bogue sur le paquet manpages-fr.

       Vous pouvez toujours avoir accès à la version anglaise de ce document en utilisant la commande « man -L C
       <section> <page_de_man> ».