Problème de linking lors de l'appel d'un .cpp
	
	
		Bonjour tout le monde,
Je fais un premier exercice qui se passait bien jusqu'à il y'a 2 minutes.
J'obtiens un message d'erreur lors du linking :
	Citation:
	
		
		
			Linking...
Vehicule3.obj : error LNK2001: unresolved external symbol "private: static bool __cdecl CLeTout::FctnTraiterLigne(class CChargeurFichierTexte const &,void *)" (?FctnTraiterLigne@CLeTout@@CA_NABVCChargeurFichierTexte@@PAX@Z)
Debug/vehicule3.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
			
		
	
 La ligne qui pose problème est celle-ci :
	Code:
	
return Chargeur.Charger(NomFichier,'\t',CLeTout::FctnTraiterLigne,this);
 car quand je fais "return true", tout se passe bien et je n'obtiens aucun message d'erreur lors de la compilation et du linking.
voici mon code : Merci d'avance pour votre aide.
beegees
Voici le fichier qui pose problème (où s'est peut être le chaine.h ou le chaine.cpp) :
	Code:
	
| 12
 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
 
 | #include <BasicConsole.h>
#include "vehicule3.h"
#include "chaine.h"
 
 
Vehicule3::Vehicule3()
:NombreDePlace(0)
{
}
 
Vehicule3::~Vehicule3()
{
}
 
CVoiture::CVoiture()
:m_VTM(0.0)
{
}
 
CVoiture::~CVoiture()
{
}
 
CTabVoitures::CTabVoitures()
:m_Nombre(0),m_Tableau(NULL)
{
}
 
CTabVoitures::~CTabVoitures()
{
}
 
CLeTout::CLeTout()
{
 
}
 
CLeTout::~CLeTout()
{
 
}
 
bool	CLeTout::Charger(const char* NomFichier)
{
 
	CChargeurFichierTexte	Chargeur;
 
 
	return Chargeur.Charger(NomFichier,'\t',CLeTout::FctnTraiterLigne,this);
} | 
 
voici le chaine.h :
	Code:
	
| 12
 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
 
 | #ifndef CHAINE_H
#define CHAINE_H
 
class CChaine
{
public:
	CChaine();																// Constructeur par défaut
	CChaine(const CChaine& Source);											// Constructeur par copie
	CChaine(const char* UneChaine);											// Constructeur spécifique
	~CChaine();																// Destructeur
 
	const char*		Chaine() const;											// Accesseur du texte de la chaîne
	bool			EstNull() const;										// Accesseur de test sur le texte (m_Chaine == NULL)
	bool			EstVide() const;										// Accesseur de test sur le texte (m_Chaine == NULL) || (m_Chaine == "")
 
	void			Vider();												// Modificateur permettant de supprimer le texte de la chaîne (on revient à NULL)
	bool			Chaine(const char* UneChaine);							// Modificateur du texte de la chaîne
 
private:
	char*			m_Chaine;												// Membre contenant l'adresse du tableau de caractères alloué dynamiquement
};
 
class CChaineComposee : private CChaine
{
public:
	CChaineComposee();														// Constructeur par défaut
	CChaineComposee(const CChaineComposee& Source);							// Constructeur par copie
	CChaineComposee(const char* UneChaine, char UnSeparateur);				// Constructeur spécifique
	~CChaineComposee();														// Destructeur
 
	long			NombreChamps() const;									// Accesseur du nombre de champs
	const char*		Champs(long Indice) const;								// Accesseur d'un champ
 
	bool			Definir(const char* UneChaine, char UnSeparateur);		// Modificateur permettant de modifier la chaîne et de générer le tableau des champs
 
private:
	bool			Decomposer(char UnSeparateur);							// Modificateur permettant de modifier la chaîne et de générer le tableau des champs
 
private:
	long			m_NbrChamps;
	char**			m_Champs;
};
 
////////////////////////////////
// Class CChargeurFichierTexte//
////////////////////////////////
 
class CChargeurFichierTexte : public CChaineComposee
 
/*Donc en fait cette classe CChargeurFichierTexte à un moment donné ce qu'elle va contenir 
comme information se sont les données d'une ligne mais déjà décomposée, sont but s'est 
d'arriver à lire une ligne du fichier texte et de la décomposer automatiquement et donc en 
servant des fonctionnalités publiques de la classe et bien on aura la possibilité de savoir 
ce qu'il y'avait comme information sur la ligne (le nombre de champs et les valeurs  sous 
forme de chaîne de caractère des différents champs) et ce qu'elle fournira en plus s'est 
une méthode de chargement où on peut passer le nom du fichier et la fonction à appeler pour 
pouvoir traiter les données d'une ligne puisque le but de la fonction charger s'est de :
 
-	lire une ligne 
-	d'appeler la fonction passer par celui qui utilise cette classe là
-	et ensuite d'exécuter cette fonction
-	et ensuite de passer à la lecture de la ligne suivante et ce jusqu'à la fin du fichier.
*/
{
public:
	CChargeurFichierTexte();
	~CChargeurFichierTexte();
 
	bool			Charger(const char* NomFichier, char UnSeparateur, bool (* FctnTraiterLigne)(const CChargeurFichierTexte&, void*), void* Contexte);
 
private:
};
 
#endif//CHAINE_H | 
 et voici le chaine.cpp :
	Code:
	
| 12
 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
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 
 | #include <BasicConsole.h>
#include "chaine.h"
#include "chaine.h"
 
 
////////////////////
// Classe CChaine //
////////////////////
 
CChaine::CChaine() //constructeur par défaut
:m_Chaine(NULL)
{
}
 
CChaine::CChaine(const CChaine& Source) //constructeur par copie
:m_Chaine(NULL)
{
	Chaine(Source.m_Chaine);
}
 
CChaine::CChaine(const char* UneChaine) //constructeur spécifique
:m_Chaine(NULL)
{
	Chaine(UneChaine);
}
 
CChaine::~CChaine() //destructeur
{
	Vider();
}
 
void CChaine::Vider()
{
	if (m_Chaine != NULL)
	{
		free(m_Chaine);
		m_Chaine = NULL;
	}
}
 
bool CChaine::Chaine(const char* UneChaine)
{
	if (UneChaine == NULL) return false;
	void* Nouveau = realloc(m_Chaine,(strlen(UneChaine)+1)*sizeof(char));
	if (Nouveau == NULL) return false;
	m_Chaine = (char*)Nouveau;
	strcpy(m_Chaine,UneChaine);
	return true;
}
 
const char* CChaine::Chaine() const
{
	return (m_Chaine != NULL) ? m_Chaine : "";
}
 
bool CChaine::EstNull() const
{
	return (m_Chaine == NULL);
}
 
bool CChaine::EstVide() const
{
	return (m_Chaine == NULL) || (m_Chaine[0] == 0);
}
 
 
////////////////////////////
// Classe CChaineComposee //
////////////////////////////
 
CChaineComposee::CChaineComposee()
:m_NbrChamps(0),m_Champs(NULL)
{
}
 
CChaineComposee::CChaineComposee(const CChaineComposee& Source)
:CChaine(Source),m_NbrChamps(0),m_Champs(NULL)
{
	if (Source.m_NbrChamps > 0)
	{
		m_Champs = (char**)malloc(Source.m_NbrChamps*sizeof(char*));
		if (m_Champs != NULL)
		{
			m_NbrChamps = Source.m_NbrChamps;
			for (long n=0; n < Source.m_NbrChamps; n++)
			{
				long PosRel = Source.m_Champs[n] - Source.m_Champs[0];
				m_Champs[n] = ((char*)Chaine()) + PosRel;
			}
		}
	}
}
 
CChaineComposee::CChaineComposee(const char* UneChaine, char UnSeparateur)
:CChaine(UneChaine),m_NbrChamps(0),m_Champs(NULL)
{
	Decomposer(UnSeparateur);
}
 
CChaineComposee::~CChaineComposee()
{
	if (m_Champs) free(m_Champs);
}
 
long CChaineComposee::NombreChamps() const
{
	return m_NbrChamps;
}
 
const char* CChaineComposee::Champs(long Indice) const
{
	return ( (Indice >= 0) && (Indice < m_NbrChamps) ) ? m_Champs[Indice] : "";
}
 
bool CChaineComposee::Definir(const char* UneChaine, char UnSeparateur)
{
	if (!Chaine(UneChaine)) return false;
	return Decomposer(UnSeparateur);
}
 
bool CChaineComposee::Decomposer(char UnSeparateur)
{
	m_NbrChamps = 0;
	char* Texte = (char*)Chaine();
	if (Texte == NULL) return false;
	void* Nouveau = realloc(m_Champs,1*sizeof(char*));
	if (Nouveau == NULL)
	{
		if (m_Champs)
		{
			free(m_Champs);
			m_Champs = NULL;
		}
		return false;
	}
	m_Champs = (char**)Nouveau;
	m_Champs[m_NbrChamps] = Texte;
	m_NbrChamps++;
	while (true)
	{
		char* Delimiteur = strchr(Texte,UnSeparateur);
		if (Delimiteur == NULL) return true;
		*Delimiteur = 0;
		Texte = Delimiteur + 1;
		void* Nouveau = realloc(m_Champs,(m_NbrChamps+1)*sizeof(char*));
		if (Nouveau == NULL) return false;
		m_Champs = (char**)Nouveau;
		m_Champs[m_NbrChamps] = Texte;
		m_NbrChamps++;
	}
}
 
 
//////////////////////////////////
// Classe CChargeurFichierTexte //
//////////////////////////////////
 
CChargeurFichierTexte::CChargeurFichierTexte()
{
}
 
CChargeurFichierTexte::~CChargeurFichierTexte()
{
}
 
bool CChargeurFichierTexte::Charger(const char* NomFichier, char UnSeparateur, bool (* FctnTraiterLigne)(const CChargeurFichierTexte&, void*), void* Contexte)
{
	const long		TailleLigne = 500;
	char			Ligne[TailleLigne+1];
	FILE*			Fichier;
 
	if ( (NomFichier == NULL) || (*NomFichier == 0) ) return false;
	Fichier = fopen(NomFichier,"rt");
	while (fgets(Ligne,TailleLigne,Fichier) != NULL)
	{
		long i = strlen(Ligne);
		if ( (i > 0) && (Ligne[i-1] == '\n') ) Ligne[i-1] = 0;
		if (Definir(Ligne,'\t'))
		{
			if (!FctnTraiterLigne(*this,Contexte))
			{
				fclose(Fichier);
				return false;
			}
		}
	}
	fclose(Fichier);
	return true;
} | 
 et pour être complet, voici le main :
	Code:
	
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | #include <BasicConsole.h>
#include "vehicule3.h"
#include "chaine.h"
 
void main()
{
 
	CLeTout LeTout;
 
	if(LeTout.Charger("Vehicules.txt")) printf("ok");
 
 
 
 
} | 
 et le header :
	Code:
	
| 12
 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
 
 | #include <BasicConsole.h>
#include "chaine.h"
 
 
class Vehicule3
{
public:
 
	Vehicule3();
	~Vehicule3();
 
 
 
	short		NombreDePlace;
 
private:
	CChaine		m_Nom;
	CChaine		m_Immatriculation;
 
};
 
class CVoiture : public Vehicule3
{
public:
	CVoiture();
	~CVoiture();
 
private:
	double		m_VTM; //Volume transportable de marchandise
 
 
};
 
class CTabVoitures
{
public:
	CTabVoitures();
	~CTabVoitures();
private:
	long		m_Nombre;
	CVoiture**	m_Tableau;
 
};
 
class CLeTout
{
public:
	CLeTout();
	~CLeTout();
 
	bool		Charger(const char* NomFichier);
 
private:
 
	private:
	static bool			FctnTraiterLigne(const CChargeurFichierTexte& CC, void* Contexte);
	bool				TraiterLigne(const CChargeurFichierTexte& CC);
 
 
private:
	CTabVoitures	m_TV; //Tableau de voitures
}; |