2010-12-10 41 views
6

Si je construis une bibliothèque partagée (objet partagé), je peux l'utiliser de deux façons:
La première façon est d'utiliser une bibliothèque partagée comme si j'utilisais une bibliothèque statique.Dilemme sur les bibliothèques partagées sous Unix

  #include "myLib.h" 
      //... 
      //afterwards I can use functions defined in mylib.h 
      myFunction(); 

La deuxième façon d'utiliser la bibliothèque partagée est en appelant les fonctions API de chargeur dynamique: dlopen, dlsym et dlclose de dlfcn.h. J'utiliserais la bibliothèque partagée de cette façon quand je veux implémenter un modèle de plugin, par exemple. Liste ressemblerait à ceci:

#include <dlfcn.h> 

void *myLib;    /* Handle to shared lib file */ 
void (*myFunction)();  /* Pointer to loaded function */ 

    //... 

    //load shared object 
    myLib = dlopen("/home/dlTest/myLib.so",RTLD_LAZY); 
    dlerror(); 

    //get handle to function 
    myFunction = dlsym(myLib, "myFunction"); 
    dlerror(); 

    //execute function 
    (*myFunction)(); 

    //close lib 
    dlclose(myLib); 
    dlerror(); 

Maintenant, ma première question est: quelle est la différence entre ces deux usages de l'objet partagé en termes de temps de chargement? En utilisant la bibliothèque partagée de la première manière, nous lions/chargons la bibliothèque partagée à l'application principale au moment du chargement et de la deuxième manière, nous faisons la même chose en cours d'exécution?

Deuxième question. Quel est le nom de ces deux usages? La première est appelée bibliothèque partagée statiquement liée et la seconde est une bibliothèque partagée dynamiquement liée/chargée?

Troisième question Si j'ai construit une bibliothèque partagée sans le drapeau -fPIC (code indépendant de l'osition), serais-je capable de l'utiliser dans un second sens?

Vive

Répondre

4

Ces deux modes d'utilisation sont généralement appelés implicites et explicites. Comme vous l'avez indiqué correctement, la différence de chargement est que la bibliothèque dynamique explicitement liée est chargée lorsque dlopen est exécuté et que la bibliothèque implicitement liée est chargée au moment du chargement de l'application en mémoire. Chaque dlopen peut prendre quelques millisecondes pour finir, sauf si la librairie est déjà chargée, auquel cas c'est très rapide, donc si vous avez des exigences de latence très strictes ou si vous avez besoin de charger/décharger fréquemment, vous pouvez charger la librairie implicitement ou explicitement au démarrage du programme et ne le déchargez pas jusqu'à ce qu'il ne soit plus utilisé.

+0

Si je modifie une bibliothèque partagée et que je la recompile, dois-je relier toutes les applications principales qui utilisent cette bibliothèque partagée si j'utilise une liaison implicite ou est-ce fait automatiquement lorsque ces applications sont chargées? –

5

La principale différence réside dans la gestion des erreurs. Implicite est plus facile, mais s'il y a un problème (la bibliothèque est manquante ou la fonction n'est pas dans la bibliothèque), le programme ne fonctionnera pas du tout. Avec le chargement explicite, vous pouvez vérifier les appels dlopen/dlsym pour les erreurs et s'il y a un problème, se rabattre sur une alternative. Pour répondre à votre troisième question, cela dépend de l'architecture, mais sur la plupart des ABI, vous pouvez toujours charger un objet partagé compilé sans -PIC, mais il peut être plus lent à charger et nécessiter plus de mémoire.

+0

Si je modifie une bibliothèque partagée et que je la recompile, dois-je relier toutes les applications principales qui utilisent cette bibliothèque partagée si j'utilise une liaison implicite ou est-ce fait automatiquement lorsque ces applications sont chargées? –

+0

@kobac: les bibliothèques non-partagées sont toujours liées lorsqu'elles sont chargées, soit au démarrage de l'application, soit à l'appel de dlopen –