dlopen | Début | Suivant | Sommaire | Préc.page.lue | Accueil |
NOM | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
SYNOPSIS | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
void *dlopen(const char *filename, int flag);
char *dlerror(void);
void *dlsym(void *handle, const char *symbol);
int dlclose(void *handle);
DESCRIPTION | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
dlerror() | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
dlopen() | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
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.)
Une des deux valeurs suivantes doit être incluse dans flag :
Zéro ou plusieurs des valeurs suivantes peuvent être spécifiées, avec un OU binaire, dans flag :
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() | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
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() | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
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() | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
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 attributs __attribute__((constructor)) et __attribute__((destructor)). Voir les pages info de 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 glibc : dladdr() et dlvsym() | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
#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; /* Pathname of shared object that contains address */ void *dli_fbase; /* Address at which shared object is loaded */ const char *dli_sname; /* Name of nearest symbol with address lower than addr */ void *dli_saddr; /* Exact address of symbol named in dli_sname */ } Dl_info;
Si aucun symbole correspondant à If no symbol matching 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 si elle réussit.
La fonction dlvsym() effectue la même chose que dlsym() mais prend une chaîne version comme argument supplémentaire.
CONFORMITÉ | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
NOTES | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Depuis la glibc 2.2.3, atexit(3) peut être utilisé pour enregistrer un gestionnaire de sortie qui sera automatiquement appelé lorsque la bibliothèque sera déchargé.
Historique | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
EXEMPLE | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
#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 */ /* Writing: cosine = (double (*)(double)) dlsym(handle, "cos"); would seem more natural, but the C99 standard leaves casting from "void *" to a function pointer undefined. The assignment used below is the POSIX.1-2003 (Technical Corrigendum 1) workaround; see the Rationale for the POSIX specification of dlsym(). */ *(void **) (&cosine) = dlsym(handle, "cos"); if ((error = dlerror()) != 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
Les bibliothèques qui exportent _init() et _fini() seront compilées comme suit, en prenant bar.c comme exemple :
VOIR AUSSI | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
TRADUCTION | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Ce document est une traduction réalisée par Christophe Blaess <http://www.blaess.fr/christophe/> le 30 août 2000 et révisée le 6 juin 2008.
L'équipe de traduction a fait le maximum pour réaliser une adaptation française de qualité. La version anglaise la plus à jour de ce document est toujours consultable via la commande : « LANG=C man 3 dlopen ». N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel.
Sommaire | Début | Suivant | Sommaire | Préc.page.lue | Accueil |
Table des mots clés | Début | Suivant | Sommaire | Préc.page.lue | Accueil |
RTLD_DEEPBIND (depuis glibc 2.3.4) | dlopen() |
RTLD_GLOBAL | dlopen() |
RTLD_LAZY | dlopen() |
RTLD_LOCAL | dlopen() |
RTLD_NODELETE (depuis la glibc 2.2) | dlopen() |
RTLD_NOLOAD (depuis la glibc 2.2) | dlopen() |
RTLD_NOW | dlopen() |