2011-06-06 8 views
2

J'ai un objet/exécutable partagé qui relie statiquement et dynamiquement à la même bibliothèque.Liaison statique et dynamique de la même bibliothèque sous Linux

Bibliothèque: liba.a et liba.so

liba.a créé à l'aide: ar -rv liba.a ao, contient (libprint) -> estampes « static5 "

liba.so créé à l'aide: gcc -o -shared liba.so -Wl, -h, liba.so ao, contient libprint() estampes "dynamic5", libprint2() estampes "dynamic6"

Exe b créé en reliant à la fois archive et objet partagé:

Lors de la liaison avec GCC/Linux, je trouve que la mise en œuvre appelée est TOUJOURS de liba.a.

J'ai une fonction libprint() définie dans liba.so, liba.a qui imprime une valeur différente. D'après ce que je vois, cela est basé sur l'ordre du lien:

gcc -ob bo liba.a liba.so -lc ./b

static5 dynamic6

de -ob gcc bo liba.so liba.a -lc ./b

dynamic5 dynamic6

Pourquoi devons-nous intentionnellement lier les fichiers .a et .so pour la même bibliothèque?:

Comment faire en sorte que l'objet partagé prenne la préférence sur l'archive, autre que l'ordre des liens? (dy/-Bdynamic ne semble pas avoir d'effet?)

1. Si l'objet partagé est manquant, l'exe échoue avec une erreur 2. Nous peut placer n'importe quel objet partagé fictif avec le même nom, juste pour satisfaire le dlopen() 3.Même une fois l'objet partagé est chargé, la fonction de l'archive est appelée

Mise à jour # 2 Voici le véritable problème (comme mentionné dans Statically and dynamically linking the same library)

libd.so est lié à l'objet partagé liba.so
ldd libd.so liba.so => ​​./liba.so

b est lié à l'objet partagé libd.so et archive liba.a.

gcc -ob bo libd.so liba.a -lc ldd b libd.so => ​​./libd.so liba.so => ​​./liba.so

Maintenant, b semble appeler d'abord la fonction de l'archive, puis l'objet partagé.

Donc, même si nous mettons à jour le liba.so, ces modifications ne seront pas reflétées dans b. Y a-t-il un moyen de contourner cela?

+0

pourrait vouloir ajouter/rechercher des balises gcc. Bonne chance. – shellter

Répondre

1

Lorsque vous placez le .a en premier, l'éditeur de liens trouve libprint() dans celui-ci et le lie, mais pas libprint2(). Il continue la recherche des bibliothèques afin de trouver l'autre fonction, et la trouve dans le .so. Lorsque vous placez le .so en premier, les deux fonctions sont trouvées et liées avec succès, il n'est donc pas nécessaire de les rechercher plus avant.

Il ne devrait pas y avoir de raison de lier à la fois les versions statiques et dynamiques de la même bibliothèque, puisque l'une ou l'autre devrait fournir toutes les fonctions trouvées dans l'autre.

+0

Merci @ ignacio-vazquez-abrams. J'ai un exécutable lié à .a et à .so. J'essaie de comprendre quelle raison il pourrait y avoir pour le faire. Le problème est que nous pouvons mettre à jour l'objet partagé, mais il ne semble pas être appelé car l'exécutable utilise toujours la fonction de l'archive d'origine. – TTA

+0

Les fichiers .a [sont liés à au moment de la construction] (http://stackoverflow.com/questions/2246799/static-library-dynamic-library-confusion/2246911#2246911). –

+0

J'ai mis à jour la question avec le cas réel. Le fichier d'objet partagé vient en premier dans la ligne de liaison, cependant, la fonction réelle est présente dans un fichier lié, et non le fichier réel. Cela entraîne toujours la récupération de la version de l'archive. – TTA

Questions connexes