2011-04-04 2 views
1

J'essaie de lier un fichier de bibliothèque statique (.a) avec un fichier .o qui utilise supposément les symboles de la bibliothèque. Cependant, lors de l'utilisation de gcc - l'erreur de l'éditeur de liens normal apparaît, indépendamment de l'utilisation du fichier .a commeg ++ vs gcc, problème de liaison avec une bibliothèque statique (.a)

gcc -L. Cependant, la même commande fonctionne parfaitement avec g ++.

Pourquoi cela se produit-il?

Je peux voir que le fichier .c est totalement légal c (et donc C++), mais alors pourquoi gcc n'est-il pas capable de détecter des symboles dans la bibliothèque? Essayé de trouver les symboles dans la bibliothèque en utilisant objdump, a pu trouver des symboles ressemblant étroitement, mais pas exactement. par exemple:

obtenu 00000000000000b0 g F .text 000000000000004e _ * Z15PhttsFn_InitTTSPh * pour le symbole * PhttsFn_InitTTS *

Quelqu'un peut-il s'il vous plaît expliquer ce phénomène? J'ai également vérifié l'architecture pour laquelle le fichier de bibliothèque a été compilé, et c'est la même chose que mon architecture.

Merci!

+0

Il semble que votre bibliothèque ait été compilée en C++, par conséquent les noms de symboles sont "mutilés" et les points d'entrée sont uniquement accessibles au code C++. –

+1

"totalement légal c (et donc C++)" C n'est pas un sous-ensemble de C++. – alternative

+0

merci pour la réponse Paul :) Mathepic, désolé - mauvais choix de mots que je vois - maintenant que je pense à ce sujet un code C juridique est illégale en C++, comme l'assignation de pointeur vide à un pointeur d'un autre genre, etc – Anonymous

Répondre

3

C++ utilise quelque chose appelé gestion des noms, pour que les espaces de noms, les noms de fonctions surchargés, etc., obtiennent des symboles uniques dans le fichier objet compilé.

Votre code C fait référence à un symbole PhttsFn_InitTTS explicitement. Maintenant, s'il est compilé en C, il produira ce même nom de symbole. Cependant, étant donné que C++ doit traiter toutes ces différentes variantes du même nom (par exemple, la surcharge, avec des listes de paramètres différentes), il crée un espace de noms de codage de version «mutilé» et des types de paramètres. Dans votre cas, il a été mutilé à Z15PhttsFn_InitTTSPh, en disant essentiellement pas d'espace de noms et pas de paramètres. (Je suppose que Z15 signifie 15 caractères, suivi d'aucune liste de paramètres).

Appeller GCC comme gcc lui permet de choisir le format de fichier lui-même, basé sur l'extension de fichier (.c -> C, .cc ou .cpp, etc -> C++). L'appeler comme g ++ force le mode C++.

Votre fichier .a est évidemment compilé en C++, car il exposait ce symbole mutilé.

+1

nice - now que vous mentionnez mangling - je me souviens avoir lu à ce sujet il y a peu de temps dans une révision rapide de C++, clairement ne pas tenir assez pour moi de déboguer cela. Merci beaucoup d'avoir répondu si clairement! – Anonymous

Questions connexes