• # Confusion link dynamique / appel dynamique

    Posté par . En réponse au journal Fonctionnement du linker dynamic sous linux. Évalué à 10.

    Je crois qu'il règne une certaine confusion entre:
    1 - un programme linké statiquement avec une lib
    2- un programme linké dynamiquement avec une lib
    3 - un programme qui n'a pas linké mais appel une (des) librairies dynamiquement au runtime.


    Cas N° 1

    Dans le premier cas, le programmeur inclut les headers de la lib qu'il veut utiliser (nom des fonctions + signature donc). Au moment de la compilation, le linker cherche les fonctions qui ne sont pas déjà dans le code link les bouts de codes externes dans un unique exécutable: au final, l'exécutable contient tous les bouts de codes externes auxquelles il fait appel (plus le code de l'éxécutable proprement, bien entendu ^^).

    Il peut donc tourner sans que les librairies qui ont servit au moment du link soient présentes sur le système. L'inconvénient est que l'exécutable est plus gros et qu'il ne profite pas des mises à jour des librairies.



    Cas N°2

    Dans le deuxième cas, tout se passe comme dans le premier cas, sauf qu'on dit au linker de linker dynamiquement. Le linker ne va pas donc pas inclure les bouts de codes externes comme un gros sale, mais va indiquer dans l'exécutable que certaines fonctions ne sont pas présentes et que l'OS devra les chercher parmis les librairies dynamiques à sa disposition avant de lancer l'exécutable. Je précise que cette recherche se fait avant que l'exécutable se lance, donc pas besoin de faire des "tests intensifs" pour savoir si toutes les libs dont le soft a besoin sont là.

    Dans ce cas, si le développeur utilise en interne une fonction qui a la même signature, le même nom et le même espace de nommage que le nom d'une fonction externe qu'il utilise également, ça ne passera pas. Mais l'erreur se produira au moment du link, et non pas lorsque l'utilisateur lancera l'exé.

    Idem, si le système ne trouve pas la lib, en question, ou que la signature attendue dans la lib diffère, alors le système refusera de lancer l'exécutable nous dira qu'il n'est pas content parcequ'il n'arrive pas à trouver telle ou telle fonction dans la lib machin-truc.



    Cas N°3

    Enfin, il y a le 3ème cas. Le développeur utilise un appel système pour dire qu'il veut utiliser les fonction "toto" de la librairie "libmachin.so". Une fois compilé, il est impossible de savoir si l'exécutable fait appel à des librairies externes et encore mois de connaître le nom des ces fonctions (Bon, si le mec veut vraiment, il pourra, ne serait-ce qu'en décompilant le soft. Et je pense que c'est plus simple que de faire exécuter tous les chemins possibles du code ^^). C'est ce qui permet notamment de charger des plug'in à la volée, sans fermer/réouvrir le soft.

    Si le système trouve la lib et la fonction au moment de l'exécution, alors tout se passe bien. Le programme a alors un pointeur de fonction (que le dév a pu appeler "toto_ext"), et s'il a déjà une fonction "toto", tout se passe bien puisque les deux n'ont pas le même nom dans le programme en question (sinon, ça n'aurait pas compilé).

    Sinon, soit le dév. a prévu le coup et tout se passe bien (on peut imaginer que le soft exprime sont mécontentement et continue avec une solution de secours ou alors se ferme). Soit le dév. a fait ça de manière un peu sale et il va manipuler un pointeur NULL, ce qui devrait aboutir tôt ou tard à un seg fault mérité :)


    PS: j'avoue que ce que je viens de raconter est basé sur mon expérience avec Windows et ses DLL, mais je suppose que c'est la même chose ou presque sous Linux.