IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Bug : error LNK2019


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2009
    Messages : 86
    Par défaut Bug : error LNK2019
    Bonjour,

    J'ai le message d'erreur suivant dans le code ci-dessous que je n'arrive pas a debugger.

    1>TestPSOR.obj : error LNK2019: symbole externe non résolu "class Vector<double,int,class FullArray<double,class std::allocator<double> > > __cdecl operator+(class Vector<double,int,class FullArray<double,class std::allocator<double> > > const &,double const &)" (??H@YA?AV?$Vector@NHV?$FullArray@NV?$allocator@N@std@@@@@@ABV0@ABN@Z) référencé dans la fonction _main
    1>TestPSOR.obj : error LNK2019: symbole externe non résolu "double __cdecl l2Norm<double,int>(class Vector<double,int,class FullArray<double,class std::allocator<double> > > const &,class Vector<double,int,class FullArray<double,class std::allocator<double> > > const &)" (??$l2Norm@NH@@YANABV?$Vector@NHV?$FullArray@NV?$allocator@N@std@@@@@@0@Z) référencé dans la fonction "public: virtual bool __thiscall MatrixIterativeSolver<double,int>::insideTolerance(void)const " (?insideTolerance@?$MatrixIterativeSolver@NH@@UBE_NXZ)
    1>C:\MyProjects\Debug\test_1.exe : fatal error LNK1120: 2 externes non résolus
    D'avance merci pour votr aide.

    Sphere369.

    TestPSOR.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
     
     
    #include "matrixsolvermechanisms.cpp"
    #include "vector.cpp"
    #include <iostream>
    #include "arraymechanisms.cpp"
    #include "matrixmechanisms.cpp"
    using namespace std;
     
     
    int main()
    {
    	// Ingredient of problem, this is
    	//
    	//	Ax >= b, x >= c
    	//	(x - c).(Ax - b) == 0 (inner product)
    	//
     
    	NumericMatrix<double, int> A(10, 10, 1, 1);		// The matrix to be inverted
    	setDiagonal(A, 2.0);
    	print(A);
     
    	Vector<double, int> b(10, 1, 1.0);			// The right-hand side vector
    	print(b);
     
    	// Constraint stuff
    	Vector<double, int> c(10, 1, 1.0);		
    	Vector<double, int> v0 = c + 1.0;
    	print(c); print(v0);
     
    	PSORSolver<double, int> mySolver(A, b, c);
     
    	/* virtual void initParameters(const V& tolerance, const V& SORFactor,
    	const I& maxIter, NormType ntype,IterativeType itype);	// hook */
    	mySolver.startVector(v0);	
    	mySolver.initParameters(0.01, 1.0, 100, L2, Jacobi);
     
    	mySolver.solve();
    	Vector<double, int> res = mySolver.result();
    	cout << "\nSolution for PSOR: \n"; print(res);
    	cout << "\nNumber of iterations: " << mySolver.NumberIterations();
    	if (mySolver.status() == false)
    		cout << "\nStatus false";
    	else
    		cout << "\nStatus true";
     
    	// Now test matrix iterative solvers using tridiagonal matrices
     
    	int J = 10;
    	Vector<double, int> a2(J-1,	2,	0.0);			// J-1 elements, start index == 2
    	Vector<double, int> b2(J, 1,	2.0);
    	Vector<double, int> c2(J-1,	1,	0.0);
    	Vector<double, int> r2(J, 1, 1.0);				// Right-hand side
    	Vector<double, int> constraintVector(J, 1, 1.0);			
     
    	NumericMatrix<double, int> m2 = createMatrix(a2, b2, c2);		
    	print(m2);
    	print(r2);
     
    	PSORSolver<double, int> mySolver2(m2, r2, constraintVector);
     
    	v0 = r2 + 1.0;		// Linear offset
    	mySolver2.startVector(v0);	
    	mySolver2.initParameters(0.01, 1.0, 100, L2, Jacobi);
     
    	mySolver2.solve();
    	Vector<double, int> result3 = mySolver2.result();
     
    	print(result3);
    	cout << "\nNumber of iterations: " << mySolver2.NumberIterations();
    	if (mySolver2.status() == false)
    		cout << "\nStatus false";
    	else
    		cout << "\nStatus true";
     
     
    	return 0;
     
    }
    Fichiers attachés Fichiers attachés

  2. #2
    Membre émérite
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include "matrixsolvermechanisms.cpp"
    #include "vector.cpp"
    #include <iostream>
    #include "arraymechanisms.cpp"
    #include "matrixmechanisms.cpp"
    Déjà des includes de fichiers cpp ça ce fait pas.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2009
    Messages : 86
    Par défaut
    Bonjour Lucien63, la je commence a m'inquiéter.... car cela parait tout a fait normale pour moi (des includes de fichiers cpp...)

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    Les fichiers en C++ se divisent en deux catégories : les fichiers d'en-têtes et les fichiers de définitions. Les premiers prennent une extension en .h (.hxx, .hpp, .hh) où 'h' est là pour souligner qu'il s'agit d'un header (fichier d'en-tête en anglais). Que trouve-t-on dans un tel fichier : globalement, les déclarations. C'est à dire le minimum que doit connaître un utilisateur (et par conséquent le compilateur) de l'unité de compilation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #ifndef A_H
    #define A_H
    class A
    {
    // déclaration de A
    };
    Les fichiers de définitions prennent l'extension .cpp (ou .cxx ou .cc). Notes que l'extension '.c' est réservée pour le C. Ces fichiers contiennent les définitions; c'est à dire l'implémentation de ce qui a été déclaré dans le fichier d'en-tête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #include "A.h"
    A::UneMethode()
    {
    }
    //...
    Dans un fichier d'en-tête on tend à minimiser les dépendances avec les autres éléments du projet en n'incluant que le strict nécessaire pour la compilation et en s'appuyant sur les déclarations anticipées au besoin.

    Dans un fichier de définition, on suit le même principe si ce n'est qu'on ne peut se contenter des déclarations anticipées dès lors qu'on utilise la classe. On inclus donc les fichiers d'en-têtes nécessaires à la compilation.

    Un projet se retrouve donc avec plusieurs couples de fichiers en-tête/définition et souvent d'un main.cpp qui ne contient pas forcément d'en-tête associé. Comment construire l'exécutable (ou la bibliothèque) ? Chaque fichier de définition (les .cpp) est compilé et produit un fichier objet intermédiaire (.o, .obj, ...). L'exécutable est ensuite produit en 'liant' les différents fichiers objets avec d'éventuelles bibliothèques (c'est la phase de link).
    Si tu travailles avec un IDE (Code::Block; Visual, etc...) celui-ci s'occupe de gérer cette chaîne de production en compilant d'abord les fichiers puis en faisant le lien.
    Si tu travailles avec un makefile, alors tu dois manuellement définir les différents fichiers à compiler ainsi que les fichiers à lier.
    Si tu compiles à la main, alors il te faut demander la compilation de chaque fichier, puis demander l'édition des liens.
    Je te conseille dans un premier temps de t'appuyer sur un I.D.E. qui t'abstraira de ces problèmes.

    Et quid des templates? Cette entrée de la FAQ devrait t'aider.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2009
    Messages : 86
    Par défaut
    Bonjour 3DArchi,

    Est ce que cela veut dire que je dois transformer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include "matrixsolvermechanisms.cpp"
    #include "vector.cpp"
    #include <iostream>
    #include "arraymechanisms.cpp"
    #include "matrixmechanisms.cpp"
    en :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #include "matrixsolvermechanisms.hpp"
    #include "vector.hpp"
    #include <iostream>
    #include "arraymechanisms.hpp"
    #include "matrixmechanisms.hpp"
    Pourtant la première option fonctionne pour d'autres programmes.
    Le problème est que la deuxième option me donne toujours le même d'erreur.

  6. #6
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 446
    Par défaut
    Outre le capharnaüm entre les fichiers d'en-tête (.hpp) et les fichiers de définitions (.cpp), les messages d'erreurs sont, pour le moins, explicite.
    Citation:
    1>TestPSOR.obj : error LNK2019: symbole externe non résolu "class Vector<double,int,class FullArray<double,class std::allocator<double> > > __cdecl operator+(class Vector<double,int,class FullArray<double,class std::allocator<double> > > const &,double const &)" (??H@YA?AV?$Vector@NHV?$FullArray@NV?$allocator@N@std@@@@@@ABV0@ABN@Z) référencé dans la fonction _main
    L'éditeur de lien ne trouve pas le code de l'opérateur plus (+) de la classe template Vector<double,int,class FullArray<double,class std::allocator<double> > >; utilisé dans la fonction _main.
    1>TestPSOR.obj : error LNK2019: symbole externe non résolu "double __cdecl l2Norm<double,int>(class Vector<double,int,class FullArray<double,class std::allocator<double> > > const &,class Vector<double,int,class FullArray<double,class std::allocator<double> > > const &)" (??$l2Norm@NH@@YANABV?$Vector@NHV?$FullArray@NV?$allocator@N@std@@@@@@0@Z) référencé dans la fonction "public: virtual bool __thiscall MatrixIterativeSolver<double,int>::insideTolerance(void)const " (?insideTolerance@?$MatrixIterativeSolver@NH@@UBE_NXZ)
    La méthode template "l2Norm" n'est pas définie (bien que déclarée dans un .h, enfin je l'espère) utilisé dans méthode "insideTolerance" de la classe "MatrixIterativeSolver".

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    Citation Envoyé par sphere369 Voir le message

    Est ce que cela veut dire que je dois transformer :
    Oui
    Citation Envoyé par sphere369 Voir le message
    Pourtant la première option fonctionne pour d'autres programmes.
    Le problème est que la deuxième option me donne toujours le même d'erreur.
    Ensuite, il faut que ton projet soit cohérent dans les différents fichiers à compile et assembler. Je pense que tu devrais d'abord t'intéresser à cette façon de faire, puis revenir sur ton problème. Ton problème de link me fait penser à différentes pistes : tu déclares la méthode mais ne la définit pas ou tu déclares un template et définit son corps dans un fichier séparé (cf FAQ sur les templates).

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2009
    Messages : 86
    Par défaut
    Je me suis emmêlé les pinceaux a force de vouloir aller trop vite. L'auteur des codes a créé dans bon nombre de ces fichiers .cpp la définition et la déclaration de ses classes (dans le même fichier .cpp)...(au lien de les mettre dans ce cas dans un fichier .hpp)

    Je vais donc reprendre les choses suivant la bonne voie en espérant que tout se passera bien.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2009
    Messages : 86
    Par défaut
    Sinon, je voudrais savoir l'intérêt réel d'ajouter un fichier fichier1.hpp a un projet lorsqu'a ce dernier il a déjà été ajouter un fichier main.cpp contenant un "#include fichier1.hpp" (tous les fichiers se trouvant dans le même répertoire).

    D'avance merci pour votre aide,

    Sphere369

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par sphere369 Voir le message
    Sinon, je voudrais savoir l'intérêt réel d'ajouter un fichier fichier1.hpp a un projet lorsqu'a ce dernier il a déjà été ajouter un fichier main.cpp contenant un "#include fichier1.hpp" (tous les fichiers se trouvant dans le même répertoire).
    Voir dans ton IDE que le fichier fait parti du projet.

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2009
    Messages : 86
    Par défaut
    Citation Envoyé par bacelar Voir le message
    La méthode template "l2Norm" n'est pas définie (bien que déclarée dans un .h, enfin je l'espère) utilisé dans méthode "insideTolerance" de la classe "MatrixIterativeSolver".
    Comment faites vous pour savoir que la méthode "l2Norm" n'est tout simplement pas définie et non pas que c'est l'éditeur de lien qui ne trouve pas son code (comme pour l'operateur + (nous avons pourtant dans ce deuxieme cas également un error LNK2019...)).

  12. #12
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par sphere369 Voir le message
    Sinon, je voudrais savoir l'intérêt réel d'ajouter un fichier fichier1.hpp a un projet lorsqu'a ce dernier il a déjà été ajouter un fichier main.cpp contenant un "#include fichier1.hpp" (tous les fichiers se trouvant dans le même répertoire).
    Parcequ'une compilation d'un executable (bibliotheque) se déroule en trois phase:
    - Précompilation
    - Compilation
    - Edition des Liens (seulement pour .exe et .so/.dll)

    L'édition des liens prend des fichiers en code "objet" (.o, .obj, .lib, ...) et les groupe ensemble pour faire un gros .exe, .dll ... Quand un de ces fichier dis appeler la fonction "totoX", alors il cherche dans tous les autres fichier l'impémentation de ce "totoX" et remplace par le bon appel. C'est là que le compilateur va raler "symbole trucmuch non trrouvé ...."

    La compilation prend un (et un seul) gros fichier (aka unité de compilation) et crée le code objet à partir de ce fichier. Tout doit y être défini. Si à un endroit on utilise la fonction totoX, celle-ci doit être déclarée (ou définie) *avant* son utilisation. Ca peut être une déclaration "externe" (comme l'est en C++ par défaut toutes les déclarations de fonctions qu'elles soient membres ou non). Ce qui veut dire que ce gros fichier *doit* contenir la déclaration de totoX.

    La précompilation permet de rendre le code plus "maintenable". Chaque "unité" de compilation (le gros fichier envoyé au compilateur) est en gérénal un fichier ".cpp". Histoire de pas avoir à modifer 40 fichier quand on modifie la fonction totoX, on utilise le système des "includes" de fichier d'en tete, avec la directive #include... Dans ce cas tous fichier .cpp qui vont utiliser la fonction totoX vont inclure "totoX.hpp" qui en fait la déclaration. Et tous les problêmes sont résolus: Une seule déclaration à un seul endroit, et tout le monde peut l'utiliser.

    J'espere avoir été assez clair

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2009
    Messages : 86
    Par défaut
    Bonjour,

    Dans le cas d'utilisation des templates c'est bel et bien le fichier .cpp qu'il faut inclure dans le programme de test (autre méthode que l'utilisation du mot clé export ou de l'utilisation de fichiers .tpp).Mon problème venait en réalité du fait que mon compilateur ne va pas chercher dans les sous répertoires du répertoire ajouté dans Pages de propriétés->C/C++ ->Général : "Autres répertoires includes".

    A bientôt,

    Sphere369

  14. #14
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par sphere369 Voir le message
    Dans le cas d'utilisation des templates c'est bel et bien le fichier .cpp qu'il faut inclure dans le programme de test (autre méthode que l'utilisation du mot clé export ou de l'utilisation de fichiers .tpp).

    Citation Envoyé par 3DArchi Voir le message
    Et quid des templates? Cette entrée de la FAQ devrait t'aider.

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2009
    Messages : 86
    Par défaut
    Bonjour,

    Sous visual c++ 2008, les fichiers .tpp ne semblent pas être reconnus.

  16. #16
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Mais on peut quand même les ajouter au projet en tant qu'entêtes et les inclure dans les autres fichiers.

    Du style

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /* MonFichier.hpp */
     
    #ifndef MONFICHIER_HPP_INCLUDED
    #define MONFICHIER_HPP_INCLUDED
     
    /* code hpp */
     
    /* ... */
     
    #include "MonFichier.tpp" /* ou MonFichier.inl, comme tu veux */
     
    #endif /* MONFICHIER_HPP_INCLUDED */

Discussions similaires

  1. error LNK2019: unresolved external symbol
    Par soniona dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 06/04/2006, 14h03
  2. Error LNK2019 avec la SDL 1.2.9
    Par dude666 dans le forum MFC
    Réponses: 1
    Dernier message: 09/02/2006, 09h12
  3. Wininet.h : error LNK2019
    Par firejocker dans le forum MFC
    Réponses: 8
    Dernier message: 10/11/2005, 18h46
  4. visual c++: error LNK2019 et fatal error LNK1120
    Par moimoi_1 dans le forum MFC
    Réponses: 2
    Dernier message: 05/11/2005, 07h41
  5. Réponses: 4
    Dernier message: 23/04/2004, 16h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo