GCC C++ Linker erreur: Undefined reference to 'vtable for XXX', Undefined reference to 'ClassName::ClassName()'
Je suis la mise en place d'un projet C++, sur Ubuntu x64, à l'aide d'Eclipse-CDT. Je suis fondamentalement de faire un hello world et en les reliant à un commerical 3ème partie de la bibliothèque.
J'ai inclus les fichiers d'en-tête, lié à leurs bibliothèques, mais je reçois encore des erreurs d'édition de liens. Y at-il des problèmes possibles, à l'exception de l'évidentes (par exemple, je suis à 99% sûr que je suis un lien vers la bibliothèque correcte).
- Est-il un moyen de confirmer les bibliothèques statiques, je suis un lien vers sont 64bit?
- Est-il un moyen de confirmer que la bibliothèque a la classe (et les méthodes), je m'attends à avoir?
Eclipse dit:
De construction cible: LinkProblem Invocation: GCC C++ Linker g++ -L/home/notroot/espace de travail/somelib-3/somelib/cible/bin -o"LinkProblem" ./src/LinkProblem.o -lsomelib1 -lpthread -lsomelib2 -lsomelib3 ./src/LinkProblem.o: In function `main': /home/notroot/espace de travail/LinkProblem/Debug/../src/LinkProblem.rpc:17: undefined reference to `SomeClass::close()' ./src/LinkProblem.o: Dans la fonction "SomeOtherClass': /home/notroot/espace de travail/somelib-3/somelib/include/sql/somefile.h:148: undefined reference to `SomeClass::SomeClass()' /home/notroot/espace de travail/somelib-3/somelib/include/sql/somefile.h:148: undefined reference to `vtable pour SomeOtherClass' /home/notroot/espace de travail/somelib-3/somelib/include/sql/somefile.h:151: undefined reference to `SomeClass::~SomeClass()' ./src/LinkProblem.o: In function `~SomeOtherClass': /home/notroot/espace de travail/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `vtable pour SomeOtherClass' /home/notroot/espace de travail/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `SomeClass::~SomeClass()' /home/notroot/espace de travail/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `SomeClass::~SomeClass()' collect2: ld a retourné 1 code de sortie make: *** [LinkProblem] Erreur 1
- Est la 3ème partie de la bibliothèque de 64 bits?
- Oui, c'est 64 bits. Vous pourriez être sur de quelque chose de bien. Comment puis-je m'assurer que mon code est 64bit? Dans Visual Studio, j'ai créé une version x64 de config.
- Est-il un moyen de confirmer la 3ème partie de la bibliothèque est en 64 bits? E. g. inspecter l' .un fichiers avec un outil ou quelque chose?
- Où est-il situé? Google montre qu'il existe un semi-convention de l'avoir dans le répertoire /usr/lib64
- La troisième partie fichiers lib êtes ici: /home/notroot/espace de travail/somelib-3/somelib/cible/bin
- merci, j'ai essayé de re-commander, pas de chance encore.
- Avez-vous essayé de googler pour la 3ème partie et 64 bits?
- pas beaucoup dans google sur eux. J'ai leurs échantillons, ils construisent amende. Je peux également faire le lien avec leurs bibliothèques sur Windows très bien (x64). Je suis en contact avec eux pour les soutenir, tout en prenant peu de temps. Probablement certains de mes difficulté ici est nouveau pour gcc/linux.
- Si vos bibliothèques ont des dépendances circulaires, vous devrez peut-être utiliser ce mécanisme: stackoverflow.com/questions/45135/linker-order-gcc/...
Vous devez vous connecter pour publier un commentaire.
En supposant que ces méthodes sont dans l'une des libs, il ressemble à une commande de problème.
Lors de la liaison des bibliothèques dans un fichier exécutable elles sont effectuées dans l'ordre où elles sont déclarées.
Aussi l'éditeur de liens ne prendra que les méthodes/fonctions nécessaires pour résoudre les actuellement en circulation dépendances. Si une nouvelle bibliothèque, puis utilise des méthodes/fonctions qui n'ont pas été tenus par les objets que vous aurez dépendances manquantes.
Comment cela fonctionne:
Exemple:
Des objets:
Lib 1 dispose:
Lib 2 fournit
Si elles sont liées comme ceci:
Alors que l'éditeur de liens ne parviennent pas à résoudre le lire et d'écrire des symboles.
Mais si je le demande comme ceci:
Puis il va se lier correctement. L2 résout le BatchRead et BatchWrite dépendances, mais ajoute également deux nouvelles (lire et écrire). Lorsque nous avons un lien avec l1 ensuite tous les quatre dépendances sont résolues.
Open
utilisé une fonction de Lib2, direBatchOpen
. Auriez-vous à fairegcc -o plop plop.o -l2 -l1 -l2
ou quelque chose comme ça?BatchOpen()
aurait déjà été liés à la demande (car il est déjà nécessaire) après la première-l2
. Ainsi, lorsque vous lien-l1
la dépendance est satisfait de ce qui est déjà dans l'application, il n'est donc pas nécessaire de lier l2 de nouveau.BatchOpen()
être nécessaire lorsqu'il analyse Lib1? Ou l'inverse: lorsque l'éditeur de liens passe par Lib2 (via-l2
) pourquoi serait-il intégrer laBatchOpen
code à ce point, car il n'a même pas vu l'exigence pour que les tiges de Lib1 deOpen
?BatchOpen
l'éditeur de liens voit que cette fonction a déjà été ajouté (à partir de l2) et des liens de manière appropriée.BatchOpen
l'éditeur de liens voit que cette fonction a déjà été ajouté (à partir de l2)". Ce que je ne comprends pas, c'est pourquoi cette fonction aurait été ajoutés précédemment. Selon votre commentaire, les symboles suivants ont été sur la liste des dépendances à un certain point:BatchRead,BatchWrite,Open,Close,Read,Write
. Pourquoi l'éditeur de liens ont souciaitBatchOpen
jusqu'à maintenant?-llibrary
paramètre, mais le programme ne serait pas un lien plus. Donc je l'ai remis et retiré la première occurrence de-llibrary
dans la liste des paramètres, et encore, il ne serait pas un lien - il uniquement fait avec succès lors de la bibliothèque a été donné deux fois. Ce fut à l'aide de gcc 4.5.2.Ce linker erreur généralement (dans mon expérience) signifie que vous avez remplacé une fonction virtuelle dans une classe enfant avec une déclaration, mais n'ont pas donné une définition de la méthode. Par exemple:
Mais vous n'avez pas donné la définition de f. Lorsque vous utilisez la classe, vous obtenez l'erreur de l'éditeur de liens. Un peu comme une normale de l'éditeur de liens d'erreur, c'est parce que le compilateur saviez de quoi vous parliez, mais l'éditeur de liens ne pouvais pas trouver la définition. C'est juste très difficile de comprendre le message.
Qt C++ montrera cette erreur lorsque vous modifiez une classe telle qu'elle hérite de QObject (c'est à dire que l'on peut maintenant utiliser des signaux/slots). L'exécution de qmake -r fera appel moc et résoudre ce problème.
Si vous travaillez avec d'autres personnes via une sorte de contrôle de version, vous aurez envie de faire quelques changements à votre .fichier pro (c'est à dire ajouter/supprimer une ligne vide). Quand tout le monde obtient vos modifications et des pistes de font, font verrez que les .pro fichier a été modifié et automatiquement exécuter qmake. Cela permettra d'économiser vos coéquipiers à partir de la répétition de votre frustration.
Le problème pour moi s'est avéré être assez obscure. Ma classe ressemblait à ceci:
Le problème est dans l'éditeur de liens. Mon fichier d'en-tête est allé dans une bibliothèque quelque part, mais toutes les fonctions virtuelles ont été déclarés 'inline' dans la déclaration de classe. Puisqu'il n'y a pas de code à l'aide de fonctions virtuelles (encore), le compilateur ou l'éditeur de liens négligé de mettre la fonction des organes en place. Il est également impossible de créer la vtable.
Dans mon code principal où j'ai tiré de cette classe, l'éditeur de liens a essayé de se connecter à ma classe de la classe de base et son vtable. Mais la vtable a été écartée.
La solution a été de déclarer au moins une des fonctions virtuelles corps en dehors de la déclaration de la classe, comme ceci:
En ce qui concerne les problèmes avec Qt4, je ne pouvais pas utiliser le qmake moc option mentionnés ci-dessus. Mais ce n'était pas le problème de toute façon. J'ai eu le code suivant dans la définition de la classe:
J'ai dû enlever la ligne "macro q_object" parce que je n'avais pas de signaux ou des emplacements définis.
J'ai eu ce message d'erreur. Le problème est que j'ai déclaré un destructeur virtuel dans le fichier d'en-tête, mais les fonctions virtuelles' corps n'était pas mis en œuvre.
Cette erreur se produit également lorsque nous avons il suffit de déclarer une fonction virtuelle sans aucune définition dans la classe de base.
Par exemple:
Modifier la déclaration ci-dessus au dessous, il fonctionnera très bien.
Dans mon cas, le problème s'est produit quand j'ai oublié d'ajouter l' =0 sur une fonction dans ma classe virtuelle pure. Il a été fixé au moment de l' =0 a été ajouté. La même que pour Frank ci-dessus.
Je suis tombé sur le problème maintenant, trop. L'application définit un pur interface virtuelle de la classe et une classe définie par l'utilisateur fourni par le biais d'un partagées lib était censé implémenter l'interface. Lors de la liaison de l'application, l'éditeur de liens se plaint que le partage des lib ne serait pas fournir vtable et type_info pour la classe de base, ils ne pourraient être trouvés n'importe où ailleurs.
S'est avéré que j'ai tout simplement oublié de faire l'une de l'interface des méthodes virtuelles pures (c'est à dire omis le "= 0" à la fin de la déclaration. Très rudimentaire, toujours facile à oublier et déroutant si vous ne pouvez pas vous connecter à l'éditeur de liens de diagnostic à la cause racine.
J'ai eu ce message d'erreur lorsque vous essayez de "hello world" comme des choses avec Qt. Les problèmes s'en alla par le bon fonctionnement de l'intervalle qt moc (compilateur de méta-objet) et de la compilation de+dont ces moc fichiers générés correctement.
Si vous avez une classe de base avec fonction virtuelle pure, assurez-vous que votre classe de base constructeur et le destructeur a le corps le contraire de l'éditeur de liens échoue.
J'ai mis ça pour les futurs visiteurs:
si vous recevez l'erreur sur la création d'un
Exception
objet, la cause est probablement un manque de définition pourwhat()
fonction virtuelle.