1 La fonction dlopen

C'est la fonction qui va permettre de charger une librairie dynamiquement dans notre programme :

1
void *dlopen(const char *filename, int flag);
  • filename : est le chemin vers la lib que l'on veut charger
  • flag : un flag pour dire comment on veut la charger

Si le chemin vers la lib que l'on veut charger n'est pas précisé, alors la fonction cherchera dans LD_LIBRARY_PATH variable globale de linux dont nous avons déjà parlé.

Voici la liste des différents flags :

  • RTLD_LAZY : Un flag de fainéant comme son nom l'indique. C'est une fonction qui ne résout que les symboles des références qui sont exécutées. Si le symbol n'est pas référencé, alors il ne sera pas résolu. (Il n'est fait que sur les références de fonctions; les références de variables sont liées quand la lib est initialisée.)
  • RTLD_NOW : Si cette valeur est spécifiée, ou si la variable d’environnement LD_BIND_NOW n'est pas une chaîne vide, tout les symboles indéfinis dans la lib seront résolus avant le retour de la fonction dlopen(). Si c'est impossible, une erreur sera retournée.

On peut ajouter des flags aux flags précédents en les mettant dans l'ordre :

  • RTLD_GLOBAL : Les symboles définis dans la lib seront disponible pour la résolution de symboles d'autres libs initialisées.
  • RTLD_LOCAL : C'est l'opposé du flag RTLD_GLOBAL, par défaut si aucun flags n'est spécifié. Les symboles définis dans la lib ne seront pas disponibles pour résoudre des références dans d'autre lib initialisée.
  • RTLD_NODELETE (depuis glibc 2.2) : Ne pas supprimée la lib pendant dlclose(). En conséquence, les variables statiques de la lib ne seront pas réinitialisées si la lib est réinitialisée avec dlopen().
  • RTLD_NOLOAD (depuis glibc 2.2) : Ne pas initialiser la lib. Peut être utiliser pour tester si la lib est résidente(dlopen() retourne NULL ce n'est pas le cas, ou si la lib est résidente). Ce flag peut être aussi utiliser pour changer les flags sur une librairie qui à déjà été initialisée. Par exemple, une lib a pu être initialisée avec RTLD_LOCAL et peut être ré-ouverte avec RTLD_NOLOAD | RTLD_GLOBAL.
  • RTLD_DEEPBIND (depuis glibc 2.3.4) : Place la recherche des symboles de la lib devant le contexte global. Cela implique qu'une lib qui se contient elle-même utilisera ses propre symboles plutôt que les symboles globaux avec les même nom que les libs qui ont déjà été initialisée.