LNK2005 Already defined erreur

Signaler
Messages postés
120
Date d'inscription
mardi 11 février 2003
Statut
Membre
Dernière intervention
9 mars 2008
-
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
-
Bonjour à tous

Je fait un projet win32 et il y a 3 fichiers

main.cpp ou il y a la fonction WinMain
PMKApp.h ou il y a la déclaration de la classe CPMKApp
PMKApp.cpp ou il y a le code des méthodes de la classe CPMKApp

dans le fichier PMKApp.h à la suite de la déclaration de la classe, je déclare un objet du type de cette classe :
#ifndef GAPP
#define GAPP
CPMKApp * g_pPMKApp; //Objet de l'application
#endif

dans le fichier main.cpp j'inclu le fichier PMKApp.h
#include "PMKApp.h"

voici le message d'erreur :

PackMan Killer error LNK2005: "class CPMKApp * g_pPMKApp" (?g_pPMKApp@@3PAVCPMKApp@@A) already defined in main.obj

Si je ne déclare pas l'objet g_pPMKApp sa ne fait pas l'erreur.

Je ne comprend pas trop pourquoi.

Merci pour le temps et l'aide.

9 réponses

Messages postés
787
Date d'inscription
samedi 8 juin 2002
Statut
Membre
Dernière intervention
7 juin 2007
1
Hum tu as du oublier de le déclarer extern peut-être (sans conviction, moi je fais plutôt du C, mais ton erreur y ressemble)
Messages postés
120
Date d'inscription
mardi 11 février 2003
Statut
Membre
Dernière intervention
9 mars 2008

Merci pour ta réponse, mais je ne comprend pas ce que tu veut dire, car moi quand j'utilise le mot clé extern c'est pour des fonction exportable dans un dll.
extern "C" __declspec(dllexport) ...
Mais la c'est rien que je veut exporter d'un dll alors je sait pas trop ce que tu veut dire, car je ne connait pas d'autres utilités au mot clef extern .

Merci pour tes précisions.
Messages postés
787
Date d'inscription
samedi 8 juin 2002
Statut
Membre
Dernière intervention
7 juin 2007
1
Cela s'utilise aussi pour déclarer un objet dans un fichier .h, de manière à ce que les fichiers .c qui l'utilisent sachent que cette variable leur est accessible bien qu'elle soit déclarée et implémentée ailleurs...

Exemple : un fichier foo.c implémente une fonction f(), qui est utilisée dans bar.c Si on déclare f() dans le .h, on aura une erreur comme celle que tu as : elle est déclarée deux fois (une fois par inclusion du .h, en fait).

La solution consiste à mettre dans le .h :

extern int f(int); // déclaration extern de f() dans foo.h

Dans foo.c :

#include "foo.h"

int f(int n) {
return n * n;
}

Et enfin, dans bar.c :

#include "foo.h"

int main(void) {
printf("%i\n", f(36));
return 0;
}

Exemple simpliste mais qui permet de cerner le problème. Après en C++, j'ignore si cela suffit, mais y'a rien à perdre à essayer :p
Messages postés
120
Date d'inscription
mardi 11 février 2003
Statut
Membre
Dernière intervention
9 mars 2008

Ok merci pour les explication c'est très clair.
Par contre dans mon cas sa ne m'aide pas, car j'ai essayer et dans ce cas sa me donne ce message d'erreur :

PackMan Killer error LNK2001: unresolved external symbol "class CPMKApp g_PMKApp" (?g_PMKApp@@3VCPMKApp@@A)

Il ne le trouve plus
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
ne JAMAIS déclarer de variables dans un .h même avec des balises #ifdef/#endif, cela provoque la multiple définition de la variable lors de l'inclusion par plusieurs fichiers sources (la compilation passe mais pas l'édition de lien).

pour s'en sortir :
dans UN fichiers .c/.cpp :
CPMKApp * g_pPMKApp; //Objet de l'application

dans les AUTRES :
extern CPMKApp * g_pPMKApp; //Objet de l'application
Messages postés
120
Date d'inscription
mardi 11 février 2003
Statut
Membre
Dernière intervention
9 mars 2008

Merci beaucoup.
Je fait sa finalement, mais dans le .h sa m'évite d'avoir à réécrire : à chaque fois.

Dans main.cpp je met :
#define MAINAPP
#include "PMKApp.h"

dans PMKApp.h je met :
#ifdef MAINAPP
#define EXTERN extern
#else
#define EXTERN
#endif
EXTERN CPMKApp g_PMKApp; //Objet de l'application

dans tous les autres fichier.cpp
#include "PMKApp.h"

Et tout sa fonctionne très bien et comme le seul endroit ou j'utilise cette variable c'est la ou le .h est inclus alors sa m'évite de la redéclarer chaque fois.
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
Ou alors, tu le définit toujours en tant que extern dans le .h et tu le met dans un des .c/.cpp sans la mot clé extern (le main par ex).
Messages postés
232
Date d'inscription
vendredi 9 janvier 2004
Statut
Membre
Dernière intervention
8 janvier 2005

extern c'est crade en C++. Il faut faire autrement, sinon c'est du (mauvais ?) C.
Je ne peux pas te donner une réponse précise, mais si tu as besoin de faire ça, alors ta conception objet est à revoir :(
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
C'est vrai que les variables globales peuvent être mis en static dans une classe et accéder facilement comme cela :

CPMKApp::g_PMKAppk;