Ce qui est une référence non définie/externe non résolu symbole d'erreur et comment la corriger?
Quels sont undefined reference/externe non résolu les erreurs de symboles? Quelles sont les causes les plus courantes et comment les corriger ou prévenir?
n'hésitez pas à modifier/ajouter votre propre.
Une chose à considérer est l'ajout de la façon de traiter avec des "undefined vtable" et "undefined typeinfo" erreurs en particulier (puisqu'ils sont moins évidents que indéfini des fonctions ou des variables).
J'ai été le marquage cette question pour être un possible dupe de celui-ci. Mais après être passé au travers de toutes vos (brillant) réponses, je ne vois pas ce cas ici. Je suis conscient que c'est spécifique à propos de la façon dont une IDE définit le type de projet et c'est le couplage des dépendances. Mais c'est une telle question souvent posée, je pense qu'il serait utile de couverts (peut-être juste avec un lien vers un autre dupe) ici. Si elle est déjà, et je n'avais pas remarqué, oublier cette demande/commentaire.
"n'hésitez pas à ajouter une réponse" j'ai préféré ajouter le lien (à mon humble avis) de votre réponse primaire, si vous souhaitez autoriser.
Erreur assez commune est que vous définissez une fonction autonome, et d'oublier le sélecteur de classe (p. ex.
Si cela vous arrive avec un signal Qt, vous avez probablement oublié la macro q_object.
J'ai été le marquage cette question pour être un possible dupe de celui-ci. Mais après être passé au travers de toutes vos (brillant) réponses, je ne vois pas ce cas ici. Je suis conscient que c'est spécifique à propos de la façon dont une IDE définit le type de projet et c'est le couplage des dépendances. Mais c'est une telle question souvent posée, je pense qu'il serait utile de couverts (peut-être juste avec un lien vers un autre dupe) ici. Si elle est déjà, et je n'avais pas remarqué, oublier cette demande/commentaire.
"n'hésitez pas à ajouter une réponse" j'ai préféré ajouter le lien (à mon humble avis) de votre réponse primaire, si vous souhaitez autoriser.
Erreur assez commune est que vous définissez une fonction autonome, et d'oublier le sélecteur de classe (p. ex.
A::
) dans votre .rpc fichier: Vous n'cette (mauvaise): void myFunc() { /* do stuff */ }
au Lieu de cela (à droite): void A::myFunc() { /* do stuff */ }
Si cela vous arrive avec un signal Qt, vous avez probablement oublié la macro q_object.
OriginalL'auteur Luchian Grigore | 2012-09-24
Vous devez vous connecter pour publier un commentaire.
La compilation d'un programme C++ se déroule en plusieurs étapes, comme spécifié par 2.2 (crédits de Keith Thompson pour la référence):
Spécifié des erreurs se produisent au cours de cette dernière étape de la compilation, plus communément appelée la liaison. Cela signifie essentiellement que vous avez compilé un groupe de fichiers de mise en œuvre dans les fichiers objets ou des bibliothèques et maintenant vous voulez les faire travailler ensemble.
Dire que vous avez défini symbole
a
dansa.cpp
. Maintenant,b.cpp
déclaré que symbole et l'a utilisé. Avant la liaison, il suppose simplement que ce symbole a été défini quelque part, mais il n'a pas encore de soins où. Le lien entre la phase est responsable de trouver le symbole et correctement le reliant àb.cpp
(eh bien, en fait, à l'objet ou à la bibliothèque qui l'utilise).Si vous êtes à l'aide de Microsoft Visual Studio, vous verrez que les projets génèrent
.lib
fichiers. Ceux-ci contiennent une table de symboles exportés, et une table de symboles importés. Les symboles importés sont résolues contre les bibliothèques de lien en face de vous, et les symboles exportés sont fournis pour les bibliothèques qui utilisent ce.lib
(le cas échéant).Des mécanismes similaires existent pour d'autres compilateurs/plates-formes.
Messages d'erreur courants
error LNK2001
,error LNK1120
,error LNK2019
pour Microsoft Visual Studio etundefined reference to
symbolName pour GCC.Le code:
va générer les erreurs suivantes avec GCC:
et des erreurs similaires avec Microsoft Visual Studio:
Les causes courantes comprennent:
#pragma
(Microsoft Visual Studio)UNICODE
définitionsSi seulement. Je pense que vous pouvez modifier de sortie à l'aide de ceci, mais je n'ai pas essayé.
Personnellement, je pense que le MS linker les messages d'erreur sont aussi lisible que la GCC erreurs. Ils ont aussi l'avantage d'inclure à la fois la déformation et unmangled noms pour les externes non résolus. Ayant la déformation d'un nom peut être utile lorsque vous avez besoin de regarder les bibliothèques ou les fichiers de l'objet directement pour voir quel peut être le problème (par exemple, une convention d'appel d'incompatibilité). Aussi, je ne suis pas certain de la version de MSVC produites les erreurs ici, mais des versions plus récentes incluent le nom (à la fois mutilé et unmangled) de la fonction de la référence le symbole externe non résolu.
David Drysdale a écrit un excellent article sur la façon dont les lieurs de travail: Guide du Débutant pour les Linkers. Étant donné le sujet de cette question, j'ai pensé qu'il pourrait s'avérer utile.
Et comment définir où est mon cas?! stackoverflow.com/questions/32915615/...
OriginalL'auteur Luchian Grigore
Les membres de la classe:
Un pur
virtual
destructeur besoins de mise en œuvre.Déclarant un destructeur pur nécessite encore à vous de le définir (à la différence d'une fonction régulière):
Cela se produit parce que classe de base les destructeurs sont appelés lorsque l'objet est détruit implicitement, si une définition est nécessaire.
virtual
méthodes doivent être mises en œuvre ou définis comme pur.Ceci est similaire à la non-
virtual
méthodes avec pas de définition, avec l'ajout de raisonnement quela pure déclaration génère un mannequin vtable et vous risquez d'obtenir l'erreur liens sans l'aide de la fonction:
Pour que cela fonctionne, déclarer
X::foo()
comme pure:Non-
virtual
les membres de la classeCertains membres ont besoin d'être définies, même si pas utilisé explicitement:
Le tableau suivant, le rendement de l'erreur:
La mise en œuvre peut être en ligne, dans la définition de la classe elle-même:
ou à l'extérieur:
Si la mise en œuvre est en dehors de la définition de la classe, mais dans un en-tête, les méthodes doivent être marqués comme
inline
pour éviter une définition de plusieurs.Utilisé des méthodes membres doivent être définis si utilisé.
Une erreur commune est d'oublier de qualifier le nom de:
La définition devrait être
static
membres de données doit être définie en dehors de la classe dans un seule unité de traduction:Un initialiseur peuvent être fournis pour un
static
const
membre de données intégrales ou de type énumération dans la définition de la classe; toutefois, rll-l'usage de ce membre aura toujours besoin d'un espace de noms définition de la portée, comme décrit ci-dessus. C++11 permet d'initialisation à l'intérieur de la classe pour tous lesstatic const
de données des membres.Pas sûr que cette partie - C++11 permet d'initialisation à l'intérieur de la classe pour tous les
static const
de données des membres est correct. [classe.statique.données]/3 dit que vous avez besoin de marquer les données membres statiquesconstexpr
si ils ne sont pas d'intégrales ou de type énumération.Pas besoin de définir n'importe quelle fonction non virtuelle vous n'utilisez jamais. Aussi, pas besoin de définir de fonction virtuelle, si vous n'avez jamais construire un objet de la classe, ni appeler à partir d'une classe dérivée de vous en fait instancier. En outre, toutes les fonctions virtuelles pures peuvent être définis.
et "devrait". Manière affectée, non-virtuelle pure fonctions doivent être définies (bien que, comme mentionné, certains compilateurs ne se plaindre jusqu'à ce que vous les appelez, mais certains). Je ne pense pas que je l'ai dit, vous ne pouvez pas définir pur virtuals.
voir "Une fonction virtuelle déclarée dans une classe doit être définie ou déclarée pure (10.4) de la classe, ou les deux; mais aucun diagnostic n'est requis" (10.3 fonctions Virtuelles) - à moins que cela est changé en C++14
OriginalL'auteur Luchian Grigore
Défaut de lien contre appropriée bibliothèques d'objets les fichiers ou compiler des fichiers de mise en œuvre
Généralement, chaque unité de traduction va générer un fichier de l'objet qui contient les définitions des symboles définis dans cette unité de traduction.
À l'utilisation de ces symboles, vous avez un lien à l'encontre de ces fichiers objets.
Sous gcc vous devez spécifier tous les fichiers objets qui doivent être reliés à la ligne de commande, ou de compiler les fichiers de mise en œuvre ensemble.
La
libraryName
ici est juste le strict nom de la bibliothèque, sans une plate-forme spécifique ajouts. Donc, par exemple, sur Linux, les fichiers de bibliothèque sont généralement appeléslibfoo.so
mais vous auriez du écrire seulement-lfoo
. Sur Windows que même fichier peut être appeléfoo.lib
, mais que vous souhaitez utiliser le même argument. Vous pourriez avoir à ajouter le répertoire où les fichiers peuvent être trouvés en utilisant-L‹directory›
. Assurez-vous de ne pas écrire une espace après-l
ou-L
.Pour XCode: Ajouter l'en-Tête Utilisateur Chemins de Recherche -> ajouter le Chemin de Recherche des bibliothèques -> faites glisser et déposez l'effectif de référence de la bibliothèque dans le dossier du projet.
Sous MSVS, les fichiers ajoutés à un projet automatiquement leurs fichiers objets liés ensemble et un
lib
le fichier généré (à usage commun). L'utilisation des symboles dans un projet distinct, vous feriezbesoin d'inclure le
lib
fichiers dans les paramètres du projet. Ceci est fait dans l'éditeur de liens de la section propriétés du projet, dansInput -> Additional Dependencies
. (le chemin d'accès à lalib
fichier doit êtreajouté dans
Linker -> General -> Additional Library Directories
) Lors de l'utilisation d'une bibliothèque tierce, qui est fourni avec unlib
fichier, à défaut de le faire est généralement le résultat dans l'erreur.Il peut aussi arriver que vous oubliez d'ajouter le fichier à la compilation, auquel cas le fichier de l'objet ne seront pas générées. Dans gcc vous ajoutez les fichiers à la ligne de commande. Dans MSVS ajouter le fichier au projet faire compiler automatiquement (bien que les fichiers peuvent, manuellement, soit individuellement exclu de la compilation).
Dans la programmation Windows, le signe révélateur que vous n'avez pas de lien nécessaire de la bibliothèque, c'est que le nom du symbole non commence avec
__imp_
. Recherchez le nom de la fonction dans la documentation, et il faut dire que la bibliothèque, vous devez utiliser. Par exemple, MSDN place les informations dans une boîte au fond de chaque fonction dans une section appelée "Bibliothèque".OriginalL'auteur Luchian Grigore
Déclarée mais n'a pas définir une variable ou une fonction.
Typique de la déclaration de la variable est
Que ce n'est qu'une déclaration, un de définition unique est nécessaire. Une définition correspondante serait:
Pour exemple, le code suivant génère une erreur:
Semblables remarques s'appliquent à des fonctions. La déclaration d'une fonction sans la définir conduit à l'erreur:
Être attentif à ce que la fonction que vous mettre en œuvre correspond exactement à celui que vous avez déclaré. Par exemple, vous avez peut-être incompatibles cv-qualificatifs:
D'autres exemples de décalages inclure
Le message d'erreur du compilateur sera souvent vous donner l'intégralité de la déclaration de la variable ou de la fonction qui a été déclaré, mais jamais défini. Comparer étroitement à la définition que vous avez fournis. Assurez-vous que tous les détails de matchs.
Les gens de la poser sur externes non résolus en raison de noms mal orthographiés, de sorte qu'il n'est pas complètement évident. (Pas sûr de ce que vous faites allusion à propos des noms de paramètres. Les noms de paramètres ne font pas partie de ce type.)
déjà couvertes par stackoverflow.com/a/12574420/673730
Dans VS, fichiers cpp associer dans l'en-tête
#includes
pas added dans le répertoire source tombe également dans la catégorie de manque de définitions.OriginalL'auteur Luchian Grigore
L'ordre dans lequel interdépendants liés bibliothèques sont spécifié est incorrect.
L'ordre dans lequel les bibliothèques sont liées importe si les bibliothèques dépendent les uns des autres. En général, si la bibliothèque
A
dépend de la bibliothèqueB
, puislibA
DOIT comparaître devantlibB
dans l'éditeur de liens drapeaux.Par exemple:
Créer les bibliothèques:
Compiler:
Donc, pour reprendre encore une fois, l'ordre NE question!
-Wl,--start-groupe .....-Wl,--fin de groupe permet de résoudre ce problème.
OriginalL'auteur Svalorzen
qu'est ce qu'un "undefined reference/symbole externe non résolu"
Je vais essayer d'expliquer ce qu'est un "undefined reference/symbole externe non résolu".
Par exemple, nous avons un peu de code
et
Faire l'objet d'fichiers
Après l'assembleur phase, nous avons un fichier de l'objet, qui contient tous les symboles à l'exportation.
Regardez les symboles
J'ai refusé certaines lignes de sortie, parce qu'ils n'ont pas d'importance
Ainsi, nous voyons suivez les symboles à l'exportation.
src2.cpp les exportations de rien et nous n'avons vu aucun de ses symboles
Le lien entre nos fichiers de l'objet
et l'exécuter
Linker voit les symboles exportés et des liens. Maintenant, nous essayons de décommenter les lignes src2.cpp comme ici
et de reconstruire un fichier objet
OK (pas d'erreurs), parce que nous ne construisons fichier de l'objet, la liaison n'est pas encore fait.
Essayez de lien
Il est arrivé à cause de nos local_var_name est statique, c'est à dire qu'il n'est pas visible pour les autres modules.
Maintenant, de plus en plus profondément. Obtenez la traduction de la phase de sortie
Donc, nous l'avons vu il n'y a pas d'étiquette pour local_var_name, c'est pourquoi l'éditeur de liens n'a pas trouvé. Mais nous sommes des pirates 🙂 et peuvent résoudre le problème. Ouvrir src1.s dans votre éditeur de texte et modifiez
à
c'est à dire, vous devriez avoir comme ci-dessous
nous avons changé la visibilité de local_var_name et définissez sa valeur à 456789.
Essayez de créer un fichier de l'objet de ce
ok, voir readelf de sortie (symboles)
maintenant local_var_name a Lier GLOBAL (été LOCAL)
lien
et l'exécuter
ok, nous hack 🙂
Donc, en tant que résultat d'un "undefined reference/externe non résolu symbol error" se produit lorsque le linker ne trouve pas les symboles globaux dans les fichiers de l'objet.
OriginalL'auteur
Symboles ont été définies dans un programme C et utilisé dans du code C++.
La fonction (ou une variable)
void foo()
a été défini dans un programme C et que vous essayez de l'utiliser dans un programme en C++:Le C++ linker attend des noms de déformation, de sorte que vous avez à déclarer la fonction:
De manière équivalente, au lieu d'être définies dans un programme C, la fonction (ou une variable)
void foo()
a été défini en C++, mais avec une liaison C:et vous essayez de l'utiliser dans un programme en C++ en C++, la liaison.
Si une bibliothèque entière est inclus dans un fichier d'en-tête (et a été compilé en code C); l'inclure devra être comme suit;
#ifdef __cplusplus [\n] extern"C" { [\n] #endif
et#ifdef __cplusplus [\n] } [\n] #endif
([\n]
être réel retour chariot, mais je ne peux pas écrire correctement en commentaire).Comme dans le commentaire ci-dessus, la Création de Langue Mixte en-Têtes de section aidé: oracle.com/technetwork/articles/servers-storage-dev/...
OriginalL'auteur Luchian Grigore
Si tout le reste échoue, recompiler.
J'ai récemment été en mesure de se débarrasser d'une erreur externe non résolu dans Visual Studio 2012 juste en recompilant les fichiers incriminés. Quand j'ai re-construit, l'erreur a disparu.
Cela se produit généralement lorsque deux (ou plus) les bibliothèques ont une dépendance cyclique. Bibliothèque de Un tente d'utiliser des symboles dans B. lib et de la bibliothèque B tente d'utiliser des symboles de A. lib. Ni exister pour commencer. Lorsque vous essayez de compiler Un, le lien de l'étape échoue, car il ne peut pas trouver de B. lib. A. lib sera généré, mais pas de dll. Vous compilez puis B, qui va réussir et de générer B. lib. Re-compiler Un va maintenant travailler parce que B. lib se trouve maintenant.
J'ai élargi sur votre réponse et lié dans la principale. Merci.
OriginalL'auteur sgryzko
Incorrecte de l'importation/exportation de méthodes/classes entre les modules/dll (compilateur spécifique).
MSVS vous oblige à spécifier les symboles à l'exportation et à l'importation à l'aide de
__declspec(dllexport)
et__declspec(dllimport)
.Cette double fonctionnalité est généralement obtenue grâce à l'utilisation d'une macro:
La macro
THIS_MODULE
ne seraient définies dans le module que les exportations de la fonction. De cette façon, la déclaration:étend à
et indique au compilateur d'exportation de la fonction, comme le module contient sa définition. Lors de l'inclusion de la déclaration dans un autre module, il permettrait d'augmenter de
et indique au compilateur que la définition est dans l'une des bibliothèques liées à l'encontre (voir aussi 1)).
Vous pouvez de même importer/exporter des classes:
visibility
et Windows.def
fichiers, qui influent également sur le nom du symbole et de la présence.Je n'ai pas utilisé
.def
fichiers dans les âges. N'hésitez pas à ajouter une réponse ou de modifier celui-ci.OriginalL'auteur Luchian Grigore
Modèle implémentations ne sont pas visibles.
Non spécialisé les modèles doivent avoir leurs définitions visible à toutes les unités de traduction qui les utilisent. Cela signifie que vous ne pouvez pas séparer la définition d'un modèle
pour un fichier d'implémentation. Si vous devez séparer la mise en œuvre, la solution de contournement est d'avoir un
impl
fichier qui vous inclure à la fin de l'en-têtedéclare le modèle. Une situation courante est:
Pour résoudre ce problème, vous devez déplacer la définition de
X::foo
pour le fichier d'en-tête ou un endroit visible de l'unité de traduction qui l'utilise.Des modèles spécialisés peuvent être mises en œuvre dans un fichier de mise en oeuvre et la mise en œuvre ne doit pas être visible, mais la spécialisation doit être préalablement déclarée.
Pour plus d'explications et une autre solution possible (instanciation explicite) voir cette question et la réponse.
OriginalL'auteur Luchian Grigore
C'est l'un des plus troublantes que les messages d'erreur que chaque VC++ programmeurs ont vu et revu. Nous allons faire les choses clarté premier.
A. Quel est le symbole?
En bref, un symbole est un nom. Il peut être un nom de variable, un nom de fonction, un nom de classe, une définition de type nom, ou quoi que ce soit à l'exception de celles des noms et des signes qui appartiennent au langage C++. Il est défini par l'utilisateur ou introduite par une dépendance de la bibliothèque (un autre défini par l'utilisateur).
B. qu'est-Ce que de l'extérieur?
Dans VC++, chaque fichier source (.rpc.c,etc.) est considéré comme une unité de traduction, le compilateur compile une unité à la fois, et de générer un fichier objet(.obj) pour le courant de l'unité de traduction. (Notez que chaque fichier d'en-tête de ce fichier source inclus sera analysée et seront considérées comme faisant partie de cette unité de traduction)le Tout dans une unité de traduction est considérée comme interne, tout le reste est considéré comme externe. En C++, vous pouvez faire référence à un symbole externe en utilisant des mots-clés comme
extern
,__declspec (dllimport)
et ainsi de suite.C. Ce qui est de “résoudre”?
Résoudre est un liant à temps. Dans le rattachement du temps, de l'éditeur de liens tentatives pour trouver la définition externe pour tous les symboles dans des fichiers objets qui ne peuvent pas trouver sa définition à l'interne. Le champ d'application de ce processus de recherche, y compris:
spécifié en tant que dépendances supplémentaires de cette demande de construire.
Ce processus de recherche est appelé à résoudre.
D. Enfin, pourquoi Symbole Externe non résolu?
Si le linker ne trouve pas la définition externe pour un symbole qui n'a pas de définition à l'interne, il signale un Symbole Externe non résolu erreur.
E. causes Possibles de LNK2019: Symbole Externe non résolu d'erreur.
Nous savons déjà que cette erreur est due à l'éditeur de liens ne trouve pas la définition de symboles externes, les causes possibles peuvent être classés comme:
Par exemple, si nous avons une fonction appelée foo définis dans a.cpp:
Dans b.cpp nous voulons appeler la fonction foo, si on l'ajoute
de déclarer la fonction foo(), et de l'appeler dans un autre corps de la fonction, dire
bar()
:Maintenant, quand vous construisez ce code, vous obtiendrez une erreur LNK2019 se plaindre que foo est un symbole non résolu. Dans ce cas, nous savons que les foo() a sa définition dans a.cpp mais différent de celui que nous appelons(différentes valeur de retour). C'est le cas de cette définition existe.
Si nous voulons appeler certaines fonctions dans une bibliothèque, mais la bibliothèque d'importation n'est pas ajouté dans le supplémentaires liste de dépendances (définie à partir de:
Project | Properties | Configuration Properties | Linker | Input | Additional Dependency
) de votre projet de création. Maintenant que l'éditeur de liens signaler un LNK2019 depuis la définition n'existe pas en courant à la recherche de la portée.OriginalL'auteur Nima Soroush
undefined reference to
WinMain@16
ou similaire inhabituellemain()
point d'entrée de référence (en particulier pour les visual-studio).Vous avez peut-être manqué de choisir le bon type de projet avec votre IDE. L'IDE peut vouloir se lier par exemple, des projets d'Application Windows à tel point d'entrée de la fonction (comme spécifié dans la référence manquante ci-dessus), au lieu de l'utiliser couramment
int main(int argc, char** argv);
signature.Si votre IDE prend en charge Plaine de la Console de Projets vous pouvez choisir ce type de projet, au lieu d'un projet d'application windows.
Voici décision1 et case2 traitées plus en détail à partir d'un monde réel problème.
WinMain
. Valide les programmes C++ besoin d'unmain
.OriginalL'auteur πάντα ῥεῖ
Aussi si vous êtes en utilisant 3ème partie les bibliothèques assurez-vous d'avoir le bon 32/64 bits binaires
OriginalL'auteur Dula
Microsoft propose une
#pragma
de référence de la bibliothèque correcte au moment de la liaison;En plus le chemin de la bibliothèque, y compris le répertoire de la bibliothèque, ce devrait être le nom complet de la bibliothèque.
OriginalL'auteur Niall
Visual Studio NuGet package doit être mis à jour pour les nouveaux outils de la version
J'ai juste eu ce problème en essayant de lier libpng avec Visual Studio 2013. Le problème est que le fichier de package seulement eu des bibliothèques pour Visual Studio 2010 et 2012.
La bonne solution est de l'espoir que le développeur publie un package de mise à jour et de le mettre à niveau, mais il a travaillé pour moi par le piratage d'un supplément de réglage pour VS2013, pointant à la VS2012 fichiers de la bibliothèque.
J'ai édité le paquet (dans le
packages
dossier à l'intérieur de la solution du répertoire) en trouvantpackagename\build\native\packagename.targets
et à l'intérieur de ce fichier, la copie de tous lesv110
sections. J'ai changé lev110
àv120
dans la condition uniquement pour les champs de être très prudent de quitter les chemins des fichiers tout commev110
. Cela a simplement permis de Visual Studio 2013 lien vers les bibliothèques pour l'année 2012, et dans ce cas, il a travaillé.Je voulais poster le ici comme cette question a été exactement ce problème, mais il a été marqué comme un double de cette question donc je ne pouvais pas répondre. Donc je l'ai posté ma réponse ici.
Cette question a déjà accepté de répondre. Il est marqué comme étant en double parce que la cause générale est listé ci-dessus. Qu'arriverait-il si nous avons eu une réponse pour chaque problème avec une bibliothèque qui n'est pas inclus?
Ce problème n'est pas spécifique à une bibliothèque, il affecte toutes les bibliothèques, à l'aide de Visual Studio, système de gestion des paquets. Je viens d'arrivé à trouver l'autre question, parce que nous avons tous les deux eu des problèmes avec libpng. J'ai également eu le même problème (avec la même solution) pour libxml2, libiconv et glew. Cette question est à propos d'un problème avec Visual Studio, système de gestion de paquets, et ma réponse explique la raison et fournit une solution de contournement. Quelqu'un a vu "externe non résolu" et supposé que c'était un standard de problème de linker quand il est en fait un paquet de problème de gestion.
OriginalL'auteur Malvineous
Supposons que vous avez un gros projet écrit en c++ qui a un mille de .fichiers cpp et un milliers de .h fichiers.Et de laisser dit que le projet repose également sur une dizaine de bibliothèques statiques. Supposons que nous sommes sur Windows et nous construisons notre projet dans Visual Studio 20xx. Lorsque vous appuyez sur Ctrl + F7 Visual Studio pour commencer à compiler l'ensemble de la solution ( supposons que nous avons un seul projet dans la solution )
Quel est le sens de la compilation ?
qui peut ou ne peut pas être défini dans le fichier .rpc
La Deuxième étape de compilation est effectuée par l'éditeur de liens.L'éditeur de liens doit fusionner tous les fichiers objets et construire enfin la sortie ( qui peut être un exécutable ou une bibliothèque)
Étapes De Liaison d'un projet
-Si l'éditeur de liens ne pouvait pas trouver le symbole qui vous écrivez dans un .rpc, il soulève un de l'éditeur de liens erreur qui peuvent sonner comme des
error LNK2001: unresolved external symbol "void __cdecl foo(void)" (?foo@@YAXXZ)
Observation
Comment Résoudre ce genre d'erreur
Compilateur Erreur :
De L'Éditeur De Liens Erreur
#pragma once
pour permettre compilateur de ne pas inclure un en-tête, si elle était déjà incluse dans l'actuel .rpc qui sont compiléesVous avez raison . Mais chaque à chaque IDE processus de compilation et de raccordement est effectué de façon légèrement différente.Mais les fichiers sont traités exactement de la même chose ( même g++ faire la même chose quand il analyser les drapeaux.. )
Le problème n'est pas réellement au sujet de l'IDE, mais sur une réponse pour lier les problèmes. Reliant les problèmes ne sont pas liés à l'IDE, mais pour le compilateur et du processus de construction.
Oui.Mais la construction/processus de liaison qui est fait dans g++/Visual Studio(compilateur fourni par Microsoft pour VS )/Eclipse/Net Beans de la même façon
OriginalL'auteur
Un bug du compilateur/IDE
J'ai récemment eu ce problème, et il s'est avéré c'était un bug dans Visual Studio Express 2013. J'ai dû supprimer un fichier source du projet et de l'ajouter de nouveau à surmonter le bug.
Étapes à suivre si vous croyez que ça pourrait être un bug dans le compilateur/IDE:
faire manuellement en supprimant les fichiers d'objet)
copier tout le code source de la version originale.
Il y a 21 réponses sur cette question et, par conséquent, une quantité importante de réponses ne vont pas à être un "probable" de la solution. Si vous faites disparaître toutes les réponses qui sont en dessous de votre seuil de probabilité alors cette page est fait devient inutile comme la plupart des affaires sont facilement repérables de toute façon.
OriginalL'auteur developerbmw
Liés .fichier lib est associée à un .dll
J'ai eu le même problème. Dire que j'ai des projets MyProject et projet d'essai. J'avais effectivement lié le fichier lib pour MyProject pour le projet d'essai. Cependant, ce fichier lib a été produit comme les DLL pour le MyProject a été construit. Aussi, je n'ai pas contenir de code source pour toutes les méthodes dans le MyProject, mais le seul accès à la DLL points d'entrée.
Pour résoudre le problème, j'ai construit le MyProject comme une LIB, et lié projet d'essai .fichier lib (j'ai copier coller le générés .fichier lib dans le projet d'essai de dossier). Je peux alors construire à nouveau MyProject comme une DLL. Il est en train de compiler depuis les lib qui Projettest est lié contient le code pour toutes les méthodes dans les classes MyProject.
OriginalL'auteur octoback
Utiliser l'éditeur de liens pour aider à diagnostiquer l'erreur
Plus modernes linkers inclure une option verbose qui imprime à des degrés divers;
Pour gcc et clang; vous pouvez généralement ajouter
-v -Wl,--verbose
ou-v -Wl,-v
à la ligne de commande. Plus de détails peuvent être trouvés ici,Pour MSVC,
/VERBOSE
(en particulier/VERBOSE:LIB
) est ajouté à la ligne de commande de liaison./VERBOSE
option de l'éditeur de liens.OriginalL'auteur Niall
Puisque les gens semblent être adressées à cette question quand il s'agit de l'éditeur de liens erreurs que je vais ajouter ici.
Une raison possible pour les erreurs d'édition de liens avec GCC 5.2.0 est qu'une nouvelle libstdc++ de la bibliothèque de l'ABI est maintenant choisi par défaut.
Donc, si vous avez soudainement obtenir de l'éditeur de liens erreurs lors du passage à un GCC après 5.1.0 ce serait une chose à vérifier.
OriginalL'auteur Plankalkül
Un wrapper autour de GNU ld qui ne supportent pas de linker scripts
Certains .si les fichiers sont en fait GNU ld linker scripts, par exemple libtbb.donc fichier est un fichier texte ASCII avec ce contenu:
Peu plus complexe construit peut pas en charge cette. Par exemple, si vous incluez -v dans les options du compilateur, vous pouvez voir que le mainwin gcc wrapper mwdip rejets linker script fichiers de commande à la sortie verbeuse liste de bibliothèques de lien. Un travail simple est de remplacer le linker script de commande d'entrée de fichier avec une copie du fichier au lieu (ou un lien symbolique), par exemple
Ou vous pouvez remplacer l'argument-l avec le chemin d'accès complet de l' .ainsi, par exemple, au lieu de
-ltbb
ne/home/foo/tbb-4.3/linux/lib/intel64/gcc4.4/libtbb.so.2
OriginalL'auteur JDiMatteo
Se lier d'amitié avec les modèles...
Donné le fragment de code d'un type de modèle avec un ami de l'opérateur (ou une fonction);
La
operator<<
est déclaré en tant que non-fonction de modèle. Pour chaque type deT
utilisé avecFoo
, il doit y avoir un non-basé sur un modèleoperator<<
. Par exemple, si il y a un typeFoo<int>
déclaré, alors il doit être un opérateur de mise en œuvre comme suit;Puisqu'il n'est pas mis en œuvre, l'éditeur de liens ne parvient pas à les trouver et les résultats dans l'erreur.
Pour corriger cela, vous pouvez déclarer un modèle d'opérateur avant la
Foo
type et de déclarer ensuite comme un ami, l'instanciation. La syntaxe est un peu maladroit, mais se présente comme suit;Le code ci-dessus les limites de l'amitié de l'opérateur correspondant à l'instanciation de
Foo
, c'est à dire laoperator<< <int>
instanciation est limité à l'accès aux membres privés de l'instanciation deFoo<int>
.Alternatives comprennent;
Permettant à l'amitié, à s'étendre à toutes les instanciations des modèles, comme suit;
Ou, de la mise en œuvre de la
operator<<
peut être fait inline à l'intérieur de la définition de la classe;Note, lors de la déclaration de l'opérateur (ou une fonction) s'affiche seulement dans la classe, le nom n'est pas disponible pour "normal" de recherche, uniquement pour l'argument dépendante de recherche, de cppreference;
Il n'y a plus de lecture sur le modèle des amis à cppreference et la C++ FAQ.
Exemple de Code montrant les techniques ci-dessus.
Comme une note de côté à l'échec de code de l'échantillon; g++ avertit à ce sujet comme suit
OriginalL'auteur Niall
Votre lien consomme bibliothèques avant que l'objet des fichiers qui parlent d'eux
libfoo
dépendlibbar
, alors votre lien correctement metlibfoo
avantlibbar
.undefined reference to
quelque chose erreurs.#include
d et sont en fait définies dans les bibliothèques que vous liez.Exemples sont en C. Elles pourraient tout aussi bien être C++
Un exemple minimal impliquant une bibliothèque statique que vous avez construit vous-même
my_lib.c
my_lib.h
eg1.c
Vous de construire votre bibliothèque statique:
Vous compilez votre programme:
Vous essayez de faire le lien avec
libmy_lib.a
et de l'échec:Le même résultat si vous compilez et liez en une seule étape, comme:
Un exemple minimal impliquant un système partagé de la bibliothèque, la bibliothèque de compression
libz
eg2.c
Compiler votre programme:
Essayer de lier votre programme avec
libz
et de l'échec:Même si vous compilez et liez en une seule fois:
Et une variante de l'exemple 2, impliquant
pkg-config
:Ce que tu fais de mal?
Dans la séquence de fichiers et bibliothèques d'objets que vous souhaitez lier à faire de votre
programme, vous placez les bibliothèques avant que l'objet des fichiers qui font référence à
. Vous devez placer les bibliothèques après les fichiers objets qui font référence
pour eux.
Lien de l'exemple 1 correctement:
Succès:
Lien exemple 2 correctement:
Succès:
Lien de l'exemple 2
pkg-config
variation correctement:L'explication
Lecture est facultative à partir d'ici sur.
Par défaut, un lien de commande généré par GCC, sur votre distribution,
consomme les fichiers dans le lien de gauche à droite dans
ligne de commande de la séquence. Quand il constate qu'un fichier se réfère à quelque chose
et ne contient pas une définition pour elle, à la recherche d'une définition
dans les fichiers vers la droite. Si elle a finalement trouve une définition, la
de référence est résolu. Si toutes les références restent en suspens à la fin,
la liaison échoue: l'éditeur de liens ne recherche pas en arrière.
D'abord, exemple 1, avec bibliothèque statique
my_lib.a
Une bibliothèque statique est indexé archive de fichiers de l'objet. Lorsque l'éditeur de liens
trouve
-lmy_lib
dans le lien de la séquence et en déduit qu'il s'agità la bibliothèque statique
./libmy_lib.a
, il veut savoir si votre programmebesoin de fichiers de l'objet dans
libmy_lib.a
.Il est seul fichier objet dans
libmy_lib.a
, à savoirmy_lib.o
, et il n'y a qu'une chose définiedans
my_lib.o
, à savoir la fonctionhw
.L'éditeur de liens décider que votre programme a besoin d'
my_lib.o
si et seulement si elle le sait déjàvotre programme se réfère à
hw
, dans un ou plusieurs des fichiers de l'objet qu'il a déjàajouté au programme, et qu'aucun des fichiers de l'objet qu'il a déjà ajouté
contient une définition pour
hw
.Si cela est vrai, alors l'éditeur de liens extraire une copie de
my_lib.o
de la bibliothèque etajouter à votre programme. Ensuite, votre programme contient une définition pour
hw
, de sorteses références à
hw
sont résolu.Lorsque vous essayez de lier le programme comme:
l'éditeur de liens n'a pas encore ajouté
eg1.o
pour le programme quand il la voit-lmy_lib
. Parce que à ce moment, il n'a pas vueg1.o
.Votre programme n'a pas encore fait aucune référence à des
hw
: iln'a pas encore fait aucune référence à tous les, parce que toutes les références qu'il fait
sont dans
eg1.o
.De sorte que le linker ne pas ajouter
my_lib.o
pour le programme et n'a plus deutiliser pour
libmy_lib.a
.Prochaine, il trouve
eg1.o
, et l'ajoute à être programme. Un fichier de l'objet dans lelien de la séquence est toujours ajouté au programme. Maintenant, le programme rend
une référence à
hw
, et ne contient pas de définition dehw
; maisil n'y a plus rien dans le lien de la séquence qui pourrait fournir le manque
définition. La référence à
hw
finit en suspens, et le couplage échoue.Deuxième, exemple 2, avec la bibliothèque partagée
libz
Une bibliothèque partagée n'est pas une archive de fichiers de l'objet ou quelque chose comme ça. C'est
beaucoup plus comme un programme qui n'ont pas de
main
fonction etau lieu de cela les expose à de multiples autres symboles qu'il définit, de sorte que les autres
les programmes peuvent utiliser lors de l'exécution.
Beaucoup de distributions Linux aujourd'hui configurer leur GCC de la chaîne de sorte que ses pilotes de langage (
gcc
,g++
,gfortran
etc)demandez au système de l'éditeur de liens (
ld
) pour lier les bibliothèques partagées sur un besoin base.Vous en avez un de ces distributions.
Cela signifie que lorsque l'éditeur de liens recherche
-lz
dans le lien de la séquence, et en déduit qu'il s'agità la bibliothèque partagée (dire)
/usr/lib/x86_64-linux-gnu/libz.so
, il veut savoir si toutes les références qu'il a ajoutée à votre programme qui ne sont pas encore définis, des définitions qui sont exportés parlibz
Si cela est vrai, alors l'éditeur de liens pas copier les morceaux de
libz
etles ajouter à votre programme; au lieu de cela, il suffit de médecin le code de votre programme
de sorte que:-
Au moment de l'exécution, le programme de système de chargeur pour charger une copie de
libz
dans lemême processus que votre programme quand il charge une copie de votre programme pour l'exécuter.
Au moment de l'exécution, toutes les fois que votre programme se réfère à quelque chose qui est défini dans
libz
, que la référence utilise la définition exportées par la copie delibz
dansle même processus.
Votre programme veut se référer à une seule chose qui a une définition exportées par
libz
,à savoir la fonction
zlibVersion
, qui est mentionné qu'une seule fois, danseg2.c
.Si l'éditeur de liens ajoute que la référence de votre programme, puis trouve la définition
exportées par
libz
, la référence est résoluMais lorsque vous essayez de lier le programme comme:
l'ordre des événements est mauvais tout simplement de la même façon que l'exemple 1.
Au moment de l'éditeur de liens recherche
-lz
, il y a pas références à rienau programme: ils sont tous dans
eg2.o
, qui n'a pas encore été vu. De sorte que lel'éditeur de liens décide qu'il n'a pas utiliser pour
libz
. Lorsqu'il atteinteg2.o
, il ajoute à ce programme,et puis a undefined reference to
zlibVersion
, le lien entre la séquence est terminée;cette référence est en suspens, et le couplage échoue.
Enfin, la
pkg-config
variation de l'exemple 2 a maintenant une explication évidente.Après shell-extension:
devient:
qui est juste à l'exemple 2 à nouveau.
Je peux reproduire le problème dans l'exemple 1, mais pas dans l'exemple 2
Le lien:
fonctionne correctement pour vous!
(Ou: ce lien a bien fonctionné pour vous, dites, Fedora 23, mais échoue sur Ubuntu 16.04)
C'est parce que la distrib sur lequel le lien fonctionne est l'un de ceux qui
ne pas configurer son GCC de la chaîne de lien bibliothèques partagées besoin.
Retour dans la journée, il était normal pour les systèmes de type unix de lien statique et partagé
les bibliothèques par des règles différentes. Les bibliothèques statiques dans un lien de séquence ont été liés
sur le besoin base expliqué dans l'exemple 1, mais les bibliothèques partagées sont liées de manière inconditionnelle.
Ce comportement est économique à linktime parce que l'éditeur de liens n'ont pas à réfléchir
si une bibliothèque partagée est requis par le programme: si c'est une librairie partagée,
un lien. Et la plupart des bibliothèques dans la plupart des liens sont des bibliothèques partagées. Mais il ya des inconvénients aussi:-
Il n'est pas rentable à runtime, car il peut causer des bibliothèques partagées pour être
chargé avec un programme, même si n'a pas besoin d'eux.
Les différentes règles d'assemblage pour les bibliothèques statiques et partagées peut être source de confusion
à inexpert programmeurs, qui ne peut pas savoir si
-lfoo
dans leur lienva le résoudre à
/some/where/libfoo.a
ou à/some/where/libfoo.so
,et pourrait ne pas comprendre la différence entre partagés et les bibliothèques statiques
de toute façon.
Ce compromis a conduit à la situation schismatique aujourd'hui. Certaines distributions ont
changé leur GCC règles d'assemblage pour les bibliothèques partagées, de sorte que le besoin
principe s'applique pour toutes les bibliothèques. Certaines distributions ont coincé avec le vieux
.
Pourquoi j'obtiens toujours ce problème, même si je compile-et-link en même temps?
Si je ne l':
sûrement gcc a pour compiler
eg1.c
d'abord, et ensuite le lien qui en résultefichier objet avec
libmy_lib.a
. Alors, comment peut-il ne pas savoir que le fichier objetest nécessaire quand il fait le lien?
Parce que la compilation et la liaison avec une seule commande ne change pas le
l'ordre de l'articulation de la séquence.
Lorsque vous exécutez la commande ci-dessus,
gcc
chiffres que vous voulez compilation +de liaison. Donc, en coulisses, il génère une compilation de commande, et s'exécute
c', puis génère un lien de commande, et l'exécute, comme si vous avait couru le
deux commandes:
De sorte que le couplage échoue juste comme il le fait si vous ne exécuter les deux commandes. L'
seule différence que l'on remarque dans l'échec est que gcc a généré un
temporaire de fichier de l'objet dans la compilation + lien de cas, parce que vous n'êtes pas la raconter
pour utiliser
eg1.o
. Nous le voyons:au lieu de:
Voir aussi
L'ordre dans lequel interdépendants liés bibliothèques sont spécifié est incorrect
Mettre interdépendants les bibliothèques dans le mauvais ordre est juste une façon
dans lequel vous pouvez obtenir les fichiers qui besoin définitions de choses à venir
plus tard dans la liaison que les fichiers qui fournir les définitions. Mettre les bibliothèques avant le
les fichiers objets qui parlent d'eux est une autre façon de faire la même erreur.
OriginalL'auteur Mike Kinghan
Incompatible
UNICODE
définitionsUn Windows version UNICODE est construit avec
TCHAR
etc. étant défini commewchar_t
etc. Lorsqu'il n'est pas de construction avecUNICODE
défini comme construire avecTCHAR
défini commechar
etc. CesUNICODE
et_UNICODE
définit une incidence sur tous les "T
" types de chaînes;LPTSTR
,LPCTSTR
et leurs élans.De la construction d'une bibliothèque avec
UNICODE
défini et à tenter de les lier dans un projet oùUNICODE
n'est pas défini entraînera des erreurs d'édition de liens, car il y aura un décalage dans la définition deTCHAR
;char
vswchar_t
.L'erreur comprend généralement une fonction d'une valeur avec un
char
ouwchar_t
type dérivé, celles-ci pourraient inclurestd::basic_string<>
etc. ainsi. Lors de la navigation par le biais de la fonction dans le code, il y aura souvent une référence àTCHAR
oustd::basic_string<TCHAR>
etc. C'est un signe révélateur que le code était à l'origine destiné à la fois une UNICODE et une de Caractères Multi-Octets (ou "étroite") construire.Pour corriger cela, créer toutes les bibliothèques requises et les projets avec une définition cohérente de
UNICODE
(et_UNICODE
).Cela peut être fait avec qui que ce soit;
Ou dans les paramètres du projet;
Ou sur la ligne de commande;
L'alternative est applicable ainsi, si l'UNICODE n'est pas destiné à être utilisé, assurez-vous que les définitions ne sont pas définies, et/ou les caractères multi-paramètre est utilisé dans les projets et appliquées de façon constante.
N'oubliez pas d'être cohérent entre la "Libération" et "Debug" construit ainsi.
OriginalL'auteur Niall
Lors de vos chemins d'accès sont différents
De l'éditeur de liens erreurs peuvent se produire lorsqu'un fichier d'en-tête et de ses associés de la bibliothèque partagée (.fichier lib) sortir de la synchronisation. Laissez-moi vous expliquer.
Comment les lieurs de travail? L'éditeur de liens correspond à une déclaration de fonction (déclarée dans l'en-tête) avec sa définition (dans la bibliothèque partagée) en comparant leurs signatures. Vous pouvez obtenir une erreur de l'éditeur de liens si le linker ne trouve pas de définition de la fonction qui correspond parfaitement.
Est-il possible de toujours obtenir un linker erreur, même si la déclaration et la définition semblent correspondre? Oui! Ils peuvent regarder la même chose dans le code source, mais cela dépend vraiment de ce que le compilateur voit. Essentiellement, vous pourriez vous retrouver avec une situation comme celle-ci:
Remarquez comment même si les déclarations de fonction identique dans le code source, mais ils sont vraiment différents selon le compilateur.
Vous pourriez vous demander comment on se retrouve dans une situation comme ça? Chemins à inclure bien sûr! Si lors de la compilation de la bibliothèque partagée, le chemin mène à
header1.h
et vous vous retrouvez à l'aide deheader2.h
dans votre propre programme, vous serez laissés gratter la tête se demandant ce qui s'est passé (pun intended).Un exemple de comment cela peut se produire dans le monde réel est expliqué ci-dessous.
La poursuite de l'élaboration d'un exemple
J'ai deux projets:
graphics.lib
etmain.exe
. Les deux projets dépendent decommon_math.h
. Supposons que la bibliothèque exportations de la fonction suivante:Et puis vous aller de l'avant et inclure la librairie dans votre propre projet.
Boom! Vous obtenez une erreur de l'éditeur de liens et vous n'avez aucune idée de pourquoi ça ne fonctionne pas. La raison en est que la bibliothèque commune utilise des versions différentes de la même inclure
common_math.h
(j'en ai fait évident ici dans l'exemple, y compris par un chemin différent, mais il n'est pas toujours si évident. Peut-être que le chemin est différent dans les paramètres du compilateur).Remarque dans cet exemple, l'éditeur de liens vous dira qu'il ne pouvait pas trouver
draw()
, alors qu'en réalité, vous savez, c'est évidemment d'être exportées par la bibliothèque. Vous pourriez passer des heures à vous gratter la tête en se demandant ce qui n'allait pas. Le truc, c'est que l'éditeur de liens voit une signature différente parce que les types de paramètres sont légèrement différentes. Dans l'exemple,vec3
est d'un type différent dans les deux projets, aussi loin que le compilateur est concerné. Cela peut se produire parce qu'ils viennent de deux légèrement différentes inclure des fichiers (peut-être les fichiers d'en venir à partir de deux versions différentes de la bibliothèque).Débogage de l'éditeur de liens
DUMPBIN est votre ami, si vous utilisez Visual Studio. Je suis sûr que d'autres compilateurs ont d'autres outils similaires.
Le processus qui va comme ceci:
[1] Par le projet, je veux dire un ensemble de fichiers sources qui sont liés ensemble pour produire une bibliothèque ou d'un fichier exécutable.
EDIT 1: Réécriture de la première section d'être plus facile à comprendre. S'il vous plaît commentaire ci-dessous pour laissez-moi savoir si quelque chose doit être corrigé. Merci!
OriginalL'auteur fafaro
Nettoyer et reconstruire
Un "nettoyage" de la construction peut supprimer le "bois mort" qui peut être laissé traîner depuis les versions précédentes, a échoué construit, incomplète construit et d'autres système de construction liés à des problèmes de génération.
En général l'IDE ou construire comprendra une certaine forme de "nettoyer" la fonction, mais cela peut ne pas être correctement configuré (par exemple, dans un manuel makefile) ou peut échouer (par exemple, l'intermédiaire ou de la résultante des fichiers binaires sont en lecture seule).
Une fois que le "propre" est terminée, vérifiez que le "propre" est un succès et tous les générées fichier intermédiaire (par exemple, un système automatisé de makefile) ont été supprimé avec succès.
Ce processus peut être vu comme un dernier recours, mais il est souvent une bonne première étape; surtout si le code lié à l'erreur qui a été ajouté récemment (localement ou à partir de la source de dépôt).
OriginalL'auteur Niall
Manquant "extern" dans
const
déclarations de variables/définitions (C++ seulement)Pour les personnes venant de C, il serait peut-être une surprise qu'en C++ mondiale
const
variables internes (ou statique) de liaison. En C, ce n'était pas le cas, toutes les variables globales sont implicitementextern
(c'est à dire lorsque lastatic
mot-clé est manquante).Exemple:
correcte serait d'utiliser un fichier d'en-tête et de les inclure dans file2.cpp et file1.cpp
Sinon on pourrait déclarer la
const
variable dans file1.cpp expliciteextern
OriginalL'auteur Andreas H.
Même si c'est une jolie vieille questions avec plusieurs réponses acceptées, je voudrais partager comment résoudre un obscur "undefined reference to" erreur.
Différentes versions de bibliothèques
J'ai été en utilisant un alias pour désigner
std::filesystem::path
: le système de fichiers est dans la bibliothèque standard depuis C++17 mais mon nécessaire à la également de compiler en C++14 j'ai donc décidé d'utiliser une variable alias:Disons que j'ai trois fichiers: main.cpp, fichier.h, file.cpp:
Note le différentes bibliothèques utilisé dans main.cpp et fichier.h. Depuis main.cpp #include d "fichier.h" après <filestystem>, la version de système de fichiers utilisé, il a été le C++17 un. J'ai utilisé pour compiler le programme avec les commandes suivantes:
$
g++ -g -std=c++17 -c main.cpp
-> compile main.cpp à main.o$
g++ -g -std=c++17 -c file.cpp
-> compile file.cpp et fichier.h à de fichier.o$
g++ -g -std=c++17 -o executable main.o file.o -lstdc++fs
-> liens principaux.o et fichier.oDe cette façon toute fonction contenues dans le fichier.o et utilisé dans la principale.o que nécessaire
path_t
a donné "undefined reference" des erreurs parce que principal.o visée àstd::filesystem::path
mais fichier.o àstd::experimental::filesystem::path
.Résolution
Pour corriger cela j'ai juste besoin de modifier <expérimentales::filestystem> dans le fichier.h <filestystem>.
OriginalL'auteur Stypox
Lors de la liaison à l'encontre de bibliothèques partagées, assurez-vous que les symboles utilisés ne sont pas cachés.
Le comportement par défaut de gcc est que tous les symboles sont visibles. Toutefois, lorsque les unités de traduction sont construits avec l'option
-fvisibility=hidden
, seules les fonctions/symboles marqués avec__attribute__ ((visibility ("default")))
sont externes dans le résultat de l'objet partagé.Vous pouvez vérifier si les symboles que vous cherchez sont à l'extérieur par l'invocation:
le caché/local symboles sont affichés par
nm
avec des minuscules type de symbole, par exemplet
au lieu de " T pour le code-section:Vous pouvez également utiliser
nm
avec l'option-C
à demangle les noms (si C++ a été utilisé).Similaire à Windows dll, on marque des fonctions publiques avec une définissent, par exemple
DLL_PUBLIC
défini comme:Qui correspond à peu près à Windows/MSVC-version:
Plus informations sur la visibilité peuvent être trouvés sur le gcc wiki.
Lorsqu'une unité de traduction est compilé avec
-fvisibility=hidden
l'résultant symboles ont toujours une liaison externe (illustré par une majuscule type de symbole parnm
) et peut être utilisé pour une liaison externe sans problème si des fichiers de l'objet de devenir une partie d'une des bibliothèques statiques. Le lien devient locale uniquement lorsque l'objet les fichiers liés dans une bibliothèque partagée.De trouver des symboles dans des fichiers objets sont cachés exécuter:
nm -CD
ounm -gCD
pour afficher les symboles externes. Voir aussi Visibilité sur la GCC wiki.OriginalL'auteur ead
Différentes architectures
Vous pouvez voir un message comme:
Dans ce cas, cela signifie que les symboles disponibles sont pour une architecture différente de celle que vous compilez pour.
Sur Visual Studio, c'est en raison de la mauvaise "Plate-forme", et vous devez sélectionner l'une ou installer la bonne version de la bibliothèque.
Sur Linux, il peut être dû à un mauvais dossier de la bibliothèque (à l'aide de
lib
au lieu delib64
par exemple).Sur MacOS, il y a l'option d'expédition en deux architectures dans le même fichier. Il se peut que le lien s'attend que les deux versions à être là, mais un seul est. Il peut aussi être un problème avec le mauvais
lib
/lib64
dossier où la bibliothèque est ramassé.OriginalL'auteur Matthieu Brucher