Problem de link?

Résolu
lesgwenos Messages postés 11 Date d'inscription dimanche 12 octobre 2003 Statut Membre Dernière intervention 23 février 2011 - 27 déc. 2009 à 22:16
lesgwenos Messages postés 11 Date d'inscription dimanche 12 octobre 2003 Statut Membre Dernière intervention 23 février 2011 - 6 janv. 2010 à 23:14
Salut,
Mon but:
Avoir une classe glEntity qui gere l'affichage openGL d'objects de classe Entity.
Mon Probleme:
undefined reference to `glEntity::ob'

Mon environement:
DevC++ sous windows XP, library openGL

Mes suppositions:
Les includes foirent?
(voir code plus bas)
Le make file foire?:
make.exe -f "C:\Documents and Settings\Administrator\My Documents\C_Dev\Project2\Makefile.win" all
g++.exe -c main.cpp -o main.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include"

g++.exe main.o -o "Project2.exe" -L"C:/Dev-Cpp/lib" -lmingw32 -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lglut32 -lglu32 -lopengl32 -lgdi32 -lm -lwinmm

Mes questions:
Qu-est-ce qui foire ?
Devrais-je utiliser des pointeurs?
Si c'est a cause du make? Comment le faire moi meme?
Je sens que je dois utiliser des fonctions 'Static' dans la class qui gere l'OpenGL mais je ne sais pas pourquoi...??


Mon code:
3 fichiers: main.cpp, Entity.h et glEntity.h:
// ------------------------main.cpp-------------------
/* Using DEV C++ and OpenGL, you need to add in your project parameters, in the linkers:
-lmingw32
-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32
-lglut32
-lglu32
-lopengl32
-lgdi32
-lm
-lwinmm
*/

#define GLUT_DISABLE_ATEXIT_HACK 
#include <windows.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
#include 

//include the 2 class files
#include "Entity.h"
#include "glEntity.h"

using namespace std;

int main (int argc, char **argv) {

    glEntity tata;
    tata.ob.Xpos=1.0;
    tata.ob.Ypos=-5.0;
    tata.ob.Zpos=-5.0;        
    glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
    glutCreateWindow ("Universe");
tata.initEntity();
    glutDisplayFunc (tata.displayEntity);
glutIdleFunc (tata.displayEntity);
cout<<"main\n";
glutReshapeFunc (tata.reshapeEntity);
    glutMainLoop ();
    return 0;
}

//-----------Entity.h-------------
#include 
using namespace std;

class Entity {
  public:
    Entity();                      // default constructor; initialize the entity
    Entity(double a,double b,double c,double d,double e,double f);  //constructor with parameters
    ~Entity();                 // Destructor; to free memory space if Entity is not needed anymore
    void doNothing();              // Do Nothing
    void cHase();                  // Chase another Entity; 
    void fLee();                   // Flee another Entity
    void mAte();                   // Mate with another Entity
    int feedBack();                // give feedback of estimation of impact with another Entity -1:the other is smaller 0:the other is equal 1:the other is bigger
    
  public:
    double Xpos;
    double Ypos;
    double Zpos;
    double Xmov;
    double Ymov;    
    double Zmov;
};
Entity::Entity(){};
Entity::Entity(double a,double b,double c,double d,double e,double f){
    Xpos=a;
    Ypos=b;
    Zpos=c;
    Xmov=d;
    Ymov=e;    
    Zmov=f;     
     };
     
Entity::~Entity(){/* cout<< "Destructing\n"; */};

//------------glEntity.h--------------

#include <stdio.h>
#include 

using namespace std;

class glEntity {
      public:
             glEntity();//Declare constructor w/o parameters
             glEntity(Entity(double a,double b,double c,double d,double e,double f));//Declare constructor with parameters             
             ~glEntity();//Declare Destructor
             void initEntity();
             static void drawEntity(Entity ob);
             static void UpdateEntity(Entity ob);
             static void displayEntity(void);
             static void reshapeEntity(int w, int h);  
             
      public:
             static Entity ob;             
      
      };

glEntity::glEntity(){};
glEntity::glEntity(Entity(double a,double b,double c,double d,double e,double f)){
                                 Entity ob(double a,double b,double c,double d,double e,double f);
                                 };
// --------init functions--------

glEntity::~glEntity(){};

void glEntity::UpdateEntity(Entity ob){

    ob.Xpos=ob.Xpos+0.001;   
 /*
 ob.Xpos=ob.Xpos+ob.Xmov;   
 ob.Ypos=ob.Ypos+ob.Ymov;
 ob.Zpos=ob.Zpos+ob.Zmov;
*/    
};

void glEntity::drawEntity(Entity ob){              // pass object ob from class Entity as paramameter to the function

    glPushMatrix();
    glTranslatef (ob.Xpos, ob.Ypos, ob.Zpos);  
    glDisable (GL_DEPTH_TEST);
    glEnable (GL_BLEND);
    glColor3f(1.0, 1.0, 1.0); //color the cube red
    glutSolidSphere (1,10, 10); //draw a solid sphere    
    glEnable(GL_DEPTH_TEST);
    glPopMatrix();
};

void glEntity::displayEntity(void){
    glClearDepth (1);
glClearColor (0.0,0.0,0.0,1.0);
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();  
glTranslatef (0,0,-10);
UpdateEntity(ob);
cout<<ob.Xpos;
    drawEntity(ob);
glutSwapBuffers();
};

void glEntity::reshapeEntity(int w, int h){
     w=100;
     h=100;
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode (GL_MODELVIEW);
};
     
void glEntity::initEntity(){
glEnable(GL_DEPTH_TEST);
ob.Xpos=2.0;
ob.Ypos=1.0;
    ob.Zpos=1.0;	
};  



Le Compile Log:
main.o(.text+0x313):main.cpp: undefined reference to `glEntity::ob'
main.o(.text+0x339):main.cpp: undefined reference to `glEntity::ob'
main.o(.text+0x351):main.cpp: undefined reference to `glEntity::ob'
main.o(.text+0x485):main.cpp: undefined reference to `glEntity::ob'
main.o(.text+0x48d):main.cpp: undefined reference to `glEntity::ob'
main.o(.text+0x495):main.cpp: more undefined references to `glEntity::ob' follow
collect2: ld returned 1 exit status

make.exe: *** [Project2.exe] Error 1

Execution terminated

J'ai du batailler pour les fonctions openGL qui prennent void en paramametre.
Maintenant je ne sais plus quoi faire.
Toutes propositions et aides sont les bienvenues

Merci

Gweno

6 réponses

cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
30 déc. 2009 à 23:25
Salut,
Quand tu déclares un membre static dans une classe, il faut le définir dans un cpp:
Entity glEntity::ob;
Normalement, ça devrait se trouver dans ton glEntity.cpp, qui devrait aussi contenir le code des méthodes de glEntity (il ne faut pas mettre l'implémentation des méthodes dans le header car c'est moche et ça risque de te poser des problèmes plus tard).
3
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
4 janv. 2010 à 23:37
Salut,
Non c'est très bien comme ça: toutes les méthodes et déclarations relatives à glEntity dans glEntity.cpp, et ton main() reste tel qu'il est dans main.cpp.
3
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
6 janv. 2010 à 21:37
Salut,
Normalement ça devrait se trouver dans ton cpp (toutes les définitions de méthodes, constructeur et destructeur inclus). Pas de code dans les headers, c'est toujours source de problèmes.
Sinon, pour des méthodes courtes (comme ton constructeur vide par exemple) tu peux toujours les définir au moment de la déclaration (et donc ne rien avoir à mettre dans ton cpp):
class glEntity
{
public:
Entity() {}
...
};
3
lesgwenos Messages postés 11 Date d'inscription dimanche 12 octobre 2003 Statut Membre Dernière intervention 23 février 2011
4 janv. 2010 à 23:27
Merci Aardman,

Je comprends qu'il me faut donc un glEntity.cpp, pour declarer le membre static + les methodes de glEntity. Faut-il donc que j'ai une fonction "int main() " dans ce glEntity.cpp qui contiendrait ce que j'ai actuellement dans le main de Main.cpp ?
Et Mon main de main.cpp n'aurait plus que les creations d'objets + appel au main de glEntity ?

Gweno
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
lesgwenos Messages postés 11 Date d'inscription dimanche 12 octobre 2003 Statut Membre Dernière intervention 23 février 2011
6 janv. 2010 à 19:32
Merci encore une fois aardman,

Je suis maintenant confronte a un autre probleme...
Peut-etre je dvrais poster dans une autre rubrique, mais voici mon probleme:

D'abord, description des 4 fichiers:

//------------- main.cpp-----------
...
#include "glEntity.cpp"
...

int main()
...


//------------- glEntity.cpp-----------
...
#include "Entity.h"
#include "glEntity.h"
...
//definition de toutes les methodes (statiques et non statiques) de la Class d'objets glEntity + membre statique
...


//------------glEntity.h--------------
#ifndef GLENTITY_H
#define GLENTITY_H
...
//classe glEntity et declaration des ses methodes (constructeur, destructeurs, methodes statiques + non statiques) + declaration membre statique
...
#endif


//-----------Entity.h-------------
#ifndef ENTITY_H
#define ENTITY_H
...
//classe Entity et declaration des methodes et membres (non statiques)
...
definition des methodes de Entity
...
#endif

Erreurs a la compilation:
Erreurs de definition multiple
glEntity.o(.text+0x100):glEntity.cpp: multiple definition of `Entity::Entity()'
main.o(.text+0x100):main.cpp: first defined here
et cela pour chacunes des methodes de Entity et glEntity...
Apres fouillage dans les forums il semble que cela est normal car a la precompilation, malgres les #ifndef, les definitions qui sont dans les headers sont copiees au moins 2 fois, via le main.cpp, et via le glEntity.cpp...
Je crois donc comprendre que les #ifndef ne marche que pour une precompile d'un fichier source.

En feuilletant les divers forum dont Codes-sources j'ai lu qu'une solution est de mettre des 'inline'... Cela ne m'arrange pas...
ou de trafiquer le make file... mais la je cale, je ne sais pas du tout manipuler cela.
Y-a-t'il d'autres solutions ?

Merci d'avance

Gweno
0
lesgwenos Messages postés 11 Date d'inscription dimanche 12 octobre 2003 Statut Membre Dernière intervention 23 février 2011
6 janv. 2010 à 23:14
Merci beaucoup pour ton aide super efficace


Gweno
0
Rejoignez-nous