Système Linux Dlopen en C

Système Linux Dlopen en C
La fonction de bibliothèque dLopen () est une fonction très utile dans le langage C. La fonction charge la bibliothèque dans la mémoire après avoir ouvert une nouvelle. Nous l'utilisons généralement pour charger les symboles de la bibliothèque qui sont inconnus au moment de la compilation. DLOpen () est une fonction utilisée dans nos programmes. La bibliothèque DL implémente dlopen (), définie dans dlfcn.H. Deux paramètres sont requis pour la fonction DLOpen: le nom du fichier de bibliothèque et l'indicateur. Le nom du fichier est une bibliothèque dynamique, et elle définit si les dépendances de la bibliothèque sont calculées immédiatement. Le dlopen () renvoie une «poignée» qui doit être considérée comme une valeur opaque et d'autres opérations de bibliothèque DL utilisent ce. Si la tentative de chargement est infructueuse, dlopen () renvoie nul. Mais le dlopen () renvoie la même poignée de fichier si elle charge la même bibliothèque plusieurs fois.

Tout en utilisant la fonction dlopen, le compilateur n'examine pas les erreurs potentielles car elle n'est pas au courant des types et des prototypes que nous utilisons. Le déploiement de la fonction DLOpen pour le chargement standard ne semble pas être promu par lui, à l'exception de quelques situations mineures. Soit dit en passant, c'est une approche pour améliorer l'introspection. Lorsque le module partagé est actuellement utilisé par un autre programme, l'optimisation de mise en page de la mémoire n'est pas particulièrement intéressée par le chargement conditionnel. L'empreinte mémoire n'augmente pas lorsqu'une bibliothèque précédemment utilisée est chargée. Éviter la surveillance du compilateur est dangereux et permet une bonne rédaction de bogues. De plus, nous n'avons pas l'optimisation possible du compilateur.

Exemple 1:

Maintenant, considérez l'exemple suivant pour voir la fonctionnalité de la fonction dlopen dans le langage C. Dans la première étape, nous chargeons quelques bibliothèques standard. Ici, nous chargeons la nouvelle bibliothèque «DLFCN.h ”qui est utilisé pour définir les macros lors de la construction de l'argument du mode dlopen.

Ensuite, nous présentons une autre bibliothèque dans notre programme «GNU / lib-name.h ”. Les fichiers de bibliothèque partagés inclus avec GNU LIBC sont trouvés par les programmes utilisateur en fonction des macros qu'il définit. La bibliothèque GNU C propose les bibliothèques fondamentales pour les systèmes d'exploitation GNU et GNU / Linux ainsi qu'une large gamme d'autres systèmes basés sur Linux. Après cela, nous avons la mise en œuvre de la méthode principale. À l'intérieur, nous déclarons l'objet de pointeur «manipuler» avec le mot-clé vide. Nous déclarons une fonction de sinus pointeur qui a le type de données double. Il existe une autre déclaration de l'objet de pointeur «Erreur» pour la gestion des erreurs.

Après cela, nous invoquons la fonction dlopen à l'intérieur de l'objet «manche». Le dlopen prend deux arguments: libm_so et "rtld_lazy". Ici, «libm_so» est le nom du fichier de bibliothèque qui fournit des fonctions mathématiques comme les fonctions trigonométriques. Cette bibliothèque partagée est requise car nous utilisons la fonction Sine. Le «rtld_lazy» est un autre argument qui appelle la fonction dlopen. Lorsqu'un symbole donné est référencé la première fois, les délocalisations doivent être effectuées à un moment déterminé par l'implémentation.

Étant donné qu'un processus peut ne pas référencer chaque symbole d'un fichier d'objet exécutable, spécifiant le RTLD Lazy doit améliorer les performances des implémentations qui permettent la liaison dynamique du symbole. Ensuite, nous avons une condition IF-Else pour la gestion des erreurs lorsque l'objet de poignée ne parvient pas à effectuer la fonction DLOpen. Nous appelons le dlerror pour effacer l'erreur.

La fonction dLerror () fournit une chaîne à terminaison nulle qui est lisible par l'homme et spécifie la déclaration de l'erreur récente qui est causée par un appel à l'un des appels API DLOpen depuis le dernier appel DLerror. Ensuite, nous avons mis la fonction comme ceci: «(* void **) (& sine) = dlsym (manche, sin)». Comme cela est étrange, le casting est conforme à l'iso C qui évite les avertissements du compilateur. Nous utilisons la fonction DLSym qui obtient le chemin d'un symbole spécifié à l'intérieur d'un module de liaison dynamique accessible via une fonction dlopen ().

De plus, nous effectuons à nouveau l'opération IF-Else pour l'erreur standard qui est générée lorsque le dlerror () n'est pas nul. Ensuite, nous avons une instruction PRINTF où nous spécifions la valeur sinusoïdale à calculer. Dans la dernière étape, nous fermons cet objet partagé en invoquant le dlclose pour la poignée renvoyée par le dlopen ().

#inclure
#inclure
#inclure
#inclure
int
Main (int argc, char ** argv)

vide * poignée;
double (* sinus) (double);
Erreur de char *;
handle = dlopen (libm_so, rtld_lazy);
si (!gérer)
fprintf (stderr, "% s \ n", dlerror ());
exit (exit_failure);

dlerror ();
* (void **) (& sine) = dlsym (manche, "sin");
if ((error = dlerror ()) != Null)
fprintf (stderr, "% s \ n", erreur);
exit (exit_failure);

printf ("% f \ n", (* sinus) (4.0));
dlclose (manche);
exit (exit_success);

Nous utilisons l'option -LDL avec la commande de compilation C car il s'agit de la bibliothèque de l'interface liée DLOpen et elle est requise. Lorsque l'exécution du fichier dlopen est effectuée, il affiche la valeur sinusoïdale de la valeur précédemment donnée.

Exemple 2:

Maintenant, nous prenons un autre exemple de l'utilisation de la fonction dlopen. Nous chargeons notre programme avec toutes les bibliothèques C requises pour l'implémentation du code DLOpen. Ensuite, nous commençons notre programme dans la méthode principale. Ici, nous définissons la chaîne avec la déclaration de la variable «SRC». Nous déclarons ensuite les variables du pointeur «strlen», «manche» et «erreur».

Ensuite, nous appelons la variable de poignée et déploie la fonction dlopen. La fonction DLOpen entre la bibliothèque partagée «LiBSTR.donc "pour les fonctions de traitement des chaînes et le drapeau" rtld_lazy "qui est déjà démontré dans l'exemple précédent. Nous invoquons la fonction DLerror à l'intérieur de la variable «Erreur» pour effacer l'erreur générée par la fonction DLOpen. L'IF-Else est utilisé pour examiner les erreurs.

Ensuite, nous obtenons l'adresse de la fonction strlen en utilisant la fonction DLSym et vérifions les erreurs tout en faisant cela. Après cela, nous utilisons la fonction printf pour appeler la fonction strnlen pour retourner la longueur de la chaîne donnée. En fin de compte, nous fermons la bibliothèque partagée avec la fonction dlclose.

#inclure
#inclure
#inclure
#inclure
int Main (vide)

char * src = "Hello Linux";
int (* strlen) (const char *);
vide * poignée;
Erreur de char *;
Handle = dlopen ("./ libstr.SO ", rtld_lazy);
error = dLerror ();
si(!manipuler || erreur != Null) printf ("La tentative de charge de la bibliothèque de chargement a échoué!\ n% s \ n ", erreur);
retour -1;
strlen = dlsym (manche, "strlen");
error = dLerror ();
si(!strlen || error == null) printf ("% s \ n", erreur); return -1;
printf ("La longueur de la chaîne est:% d \ n", strlen (src));
dlclose (manche);
retour 0;

Nous utilisons la commande suivante pour l'exécution du programme donné. Ici, l'indicateur -lstr est utilisé pour la fonction de longueur de chaîne et le LDL est utilisé pour le fichier de bibliothèque DLOpen. Le programme compilé donne la longueur de la chaîne comme indiqué dans le shell:

Conclusion

Les informations sont fournies concernant la fonction dlopen du langage C dans cet article. Nous avons une brève introduction de la fonction dlopen. Ensuite, nous avons mis en œuvre deux exemples. La fonction renvoie un identifiant qui définit la bibliothèque ouverte. Les adresses des fonctions à l'intérieur de la bibliothèque ouverte sont ensuite déterminées à l'aide de cet identifiant et de la fonction DLSym. L'adresse d'une fonction dans une bibliothèque qui a déjà été ouverte à l'aide de DLOpen peut être trouvée en utilisant la fonction DLSym.