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 :

[Class] Problème avec définitions multiples


Sujet :

C++

  1. #1
    Membre à l'essai
    Inscrit en
    Juillet 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 17
    Points : 10
    Points
    10
    Par défaut [Class] Problème avec définitions multiples
    Bonjour.

    J'ai deux classes, CInit (qui contient la fonction InitSDL) et CBMP (qui contient la fonction ShowBMP), ces deux class font appels à screen qui est déini de la manière suivante (dans cinit.cpp) :
    SDL_Surface *screen;
    Mon problème : comment rendre screen utilisable par les deux fonctions ?

    J'ai utilisé un fichier .h intermédiaire, mais j'ai eu un problème de multiple définition de screen (malgrès l'utilisation de #ifndef, etc.).

    Merci.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #ifndef CINIT_H
    #define CINIT_H
     
    class CInit
    {
    	public:
    		CInit();
    		virtual ~CInit(void);
            void InitSDL(int,int,int,int);
    };
     
    #endif
    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
    #include "include.h"
    #include "cinit.h"
     
    CInit::CInit()
    {
    }
     
    CInit::~CInit()
    {
    }
     
    SDL_Surface *screen;
     
    // Fonction d'initialisation de SDL
    extern "C" __declspec(dllexport) void InitSDL(int x,int y,int bpp,int fullscreen)
    {
        Uint32 flagsinit=SDL_HWSURFACE|SDL_DOUBLEBUF;
    	if (fullscreen)
    		flagsinit|=SDL_FULLSCREEN;
    	SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER);
        if(SDL_Init(SDL_INIT_VIDEO) == -1)
        {
            printf("Impossible d'initialiser SDL :  %s\n", SDL_GetError());
            exit(1);
        }
        atexit(SDL_Quit);
    	screen=SDL_SetVideoMode(x,y,bpp,flagsinit);  
        if(screen == NULL)
        {
            printf("Imposible de régler les paramètres vidéos : %s\n", SDL_GetError());
            exit(1);
        }   
    	SDL_ShowCursor(0);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #ifndef CBMP_H
    #define CBMP_H
     
    class CBMP
    {
    	public:
    		CBMP();
    		virtual ~CBMP(void);
    		void ShowBMP(const char*);
    };
     
    #endif
    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
    #include "include.h"
    #include "cbmp.h"
     
    CBMP::CBMP()
    {
    }
     
    CBMP::~CBMP()
    {
    }
     
    SDL_Surface *image;
     
    extern "C" __declspec(dllexport) void ShowBMP(const char* NomImage)
    {
        image = SDL_LoadBMP(NomImage);
        if(image == NULL)
        {
            printf("Impossible de charger l'image : %s\n", SDL_GetError());
            exit(1);
        }
        SDL_BlitSurface(image, NULL, screen, NULL);
        SDL_FreeSurface(image);
        SDL_UpdateRect(screen, 0, 0, 0, 0);
    }
    PS: j'utilise Dev-c++ 4.9.9.0

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Août 2003
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 247
    Points : 276
    Points
    276
    Par défaut
    Tu te demande donc comment plusieurs classes peuvent accèder à une variable globale.

    Dans un .cpp, tu définit la variable:
    T global;


    Dans un .h, tu la déclare ainsi:
    extern T global;

  3. #3
    Membre à l'essai
    Inscrit en
    Juillet 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Merci pour l'aide

    Mais je viens de laisser tomber les variables globales, d'après ce que j'ai lu, c'est pas terrible :s

    Par contre j'ai un autre petit problème que je ne comprend vraiment pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #ifndef CINIT_H
    #define CINIT_H
     
    class CInit
    {
    	public:
    		CInit();
    		virtual ~CInit(void);
    		static SDL_Surface *screen;
            void InitSDL(int,int,int,int);
    };
     
    #endif
    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
    #include "include.h"
    #include "cinit.h"
     
    CInit::CInit()
    {
    }
     
    CInit::~CInit()
    {
    }
     
    // Fonction d'initialisation de SDL
    extern "C" __declspec(dllexport) void CInit::InitSDL(int x,int y,int bpp,int fullscreen)
    {
        Uint32 flagsinit=SDL_HWSURFACE|SDL_DOUBLEBUF;
    	if (fullscreen)
    		flagsinit|=SDL_FULLSCREEN;
    	SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER);
        if(SDL_Init(SDL_INIT_VIDEO) == -1)
        {
            printf("Impossible d'initialiser SDL :  %s\n", SDL_GetError());
            exit(1);
        }
        atexit(SDL_Quit);
    	CInit::screen=SDL_SetVideoMode(x,y,bpp,flagsinit);  
        if(CInit::screen == NULL)
        {
            printf("Imposible de régler les paramètres vidéos : %s\n", SDL_GetError());
            exit(1);
        }   
    	SDL_ShowCursor(0);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #ifndef CBMP_H
    #define CBMP_H
     
    class CBMP : public CInit
    {
    	public:
    		CBMP();
    		virtual ~CBMP(void);
    		void ShowBMP(const char*);
    };
     
    #endif
    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
    #include "include.h"
    #include "cinit.h"
    #include "cbmp.h"
     
    CBMP::CBMP()
    {
    }
     
    CBMP::~CBMP()
    {
    }
     
    SDL_Surface *image;
     
    extern "C" __declspec(dllexport) void CBMP::ShowBMP(const char* NomImage)
    {
        image = SDL_LoadBMP(NomImage);
        if(image == NULL)
        {
            printf("Impossible de charger l'image : %s\n", SDL_GetError());
            exit(1);
        }
        SDL_BlitSurface(image, NULL, CInit::screen, NULL);
        SDL_FreeSurface(image);
        SDL_UpdateRect(CInit::screen, 0, 0, 0, 0);
    }
    A présent, ma classe CBMP hérite de CInit, screen est bien un membre public.
    Pourtant, voici les erreurs que j'ai à la compilation :

    Intermediaire/cinit.o(.text+0x197):cinit.cpp: undefined reference to `CInit::screen'
    Intermediaire/cinit.o(.text+0x19d):cinit.cpp: undefined reference to `CInit::screen'
    Intermediaire/cbmp.o(.text+0x165):cbmp.cpp: undefined reference to `CInit::screen'

    Intermediaire/cbmp.o(.text+0x1b0):cbmp.cpp: undefined reference to `CInit::screen'
    Je ne comprend vraiment pas d'où viennent ces erreurs :s

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 15
    Points : 18
    Points
    18
    Par défaut
    si je dis pas de betises, ta surface, qui est en static, doit etre definie, or tu defini une surface "image" mais pas screen, il faudrait mettre :

    EDIT:

    SDL_Surface* CInit::screen = SDL_SetVideoMode(...);

  5. #5
    Membre à l'essai
    Inscrit en
    Juillet 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    cinit.cpp: In member function `void CInit::InitSDL(int, int, int, int)':
    cinit.cpp:25: error: redeclaration of `SDL_Surface*CInit::screen'
    cinit.h:9: error: `SDL_Surface*CInit::screen' previously declared here
    screen est bien définie dans cinit.h:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class CInit
    {
    	public:
    		CInit();
    		virtual ~CInit(void);
    		static SDL_Surface *screen;
    	private:
            void InitSDL(int,int,int,int);
    };

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 15
    Points : 18
    Points
    18
    Par défaut
    non, screen est declaré mais pas defini, il faut definir les variables statiques comme si tu declarait une fonction... c'est logique d'ailleurs, parce que, imagine un compteur d'instances d'une classes, il faut bien dire qu'il est égal à 0 quelque part... et comme tu ne peux pas le dire dans un constucteur, puisque c'est du static, et que tu ne peux pas affecter une valeur à une variable dans la declaration de la classe (à part les constantes), il faut bien le dire quelque part

  7. #7
    Membre à l'essai
    Inscrit en
    Juillet 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Ha ok :s

    Mais dans ce cas, le compilateur ne devrait pas me dire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cinit.cpp:25: error: redeclaration of `SDL_Surface*CInit::screen'
    cinit.h:9: error: `SDL_Surface*CInit::screen' previously declared here

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 15
    Points : 18
    Points
    18
    Par défaut
    en effet... heu, me serais-je trompé? attend j'essaie

  9. #9
    Membre à l'essai
    Inscrit en
    Juillet 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Oké merci bien.

    (Le projet à besoin de SDL : http://www.libsdl.org)

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 15
    Points : 18
    Points
    18
    Par défaut
    euh, j'ai pas d'erreurs... j'ai simplifié grangement la chose mais j'ai pas d'erreurs... je te donne ce que j'ai :

    head.h :
    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
    #ifndef __HEAD__
    #define __HEAD__
     
    #include <windows.h>
    #include <SDL.h>
    #pragma comment(lib, "SDL.lib")
    #pragma comment(lib, "SDLmain.lib")
     
    class CInit {
    public: 
    	CInit(); 
    	virtual ~CInit(void); 
    	static SDL_Surface *screen; 
    private: 
    	void InitSDL(int,int,int,int);
    };
     
    #endif
    definitions.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #include "head.h"
     
    SDL_Surface* CInit::screen = SDL_SetVideoMode (800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN);
    main.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include "head.h"
     
     
     
    int main (int argc, char **argv) {
    	return 0;
    };

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 15
    Points : 18
    Points
    18
    Par défaut
    le truc, c'est que je comprend pas trop tes extern "C" et donc j'ai pas trop envie de me risquer à tester la suite, mais une chose est sure, l'erreur ne vient pas de screen

  12. #12
    Membre à l'essai
    Inscrit en
    Juillet 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Arg, c'est vraiment zarb :s

    Tu peux essayer sans simplifier ?



    Edit : Pour les extern "C" __declspec(dllexport) mafonction

    C'est parceque le projet généré est une dll



    Edit 2 : Vla les sources complétes http://www.megaupload.com/?d=23UZKY3F

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 15
    Points : 18
    Points
    18
    Par défaut
    bon je teste mais sans les extern, j'espere que ca changera rien

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 15
    Points : 18
    Points
    18
    Par défaut
    CInit.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
    #include "CInit.h"
     
    SDL_Surface* CInit::screen = SDL_SetVideoMode (800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN);
     
    CInit::CInit() {};
    CInit::~CInit() {};
     
    void CInit::InitSDL(int x, int y, int z, int full) {
    	SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER); 
        if(SDL_Init(SDL_INIT_VIDEO) == -1) { 
            printf("Impossible d'initialiser SDL :  %s\n", SDL_GetError()); 
            exit(1);
        }
     
    	atexit(SDL_Quit);
    	SDL_FreeSurface(this->screen); /*bah oui, on l'a declaree + haut, ca serait peut etre optimisable mais bon pour gagner qqs millisecondes au demmarage...*/
     
    	Uint32 flagsinit = (full) ? SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN : SDL_HWSURFACE | SDL_DOUBLEBUF;
    	CInit::screen=SDL_SetVideoMode(x, y, z, flagsinit);
     
    	if(CInit::screen == NULL) { 
            printf("Imposible de régler les paramètres vidéos : %s\n", SDL_GetError()); 
            exit(1); 
        }
    }
    Voila j'ai un peu modifié à ma sauce, en tout cas ca passe, essaie et si ca marche tjs pas on verra avec l'autre classe

    EDIT : ca n'a aucun rapport, mais faudrait penser à mettre un SDL_FreeSurface dans le destructeur
    EDIT2 : enfin non faudrait le mettre a la fin de main en fait
    EDIT3 : j'arrive pas a compiler ton programme avec dev (faut dire que d'hab j'utilise VC++) il me dit "Could not create executable output directory : "Release". Please check your settings." je sais pas trop ce qu'il faut faire la...

  15. #15
    Membre à l'essai
    Inscrit en
    Juillet 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Bon, ça me vire le "redeclaration of `SDL_Surface*CInit::screen'" mais j'ai toujours les erreurs du type " [Linker error] undefined reference to `CInit::screen'".

    Pour l'erreur que tu as avec dev, vas dasn Projet, Options du projet, onglet Construction, et changes les répertoires

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 15
    Points : 18
    Points
    18
    Par défaut
    ok, bon je regarde actuellement ta classe CBMP, et je me demande a quoi sert la surface image exactement?

  17. #17
    Membre à l'essai
    Inscrit en
    Juillet 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    La surface image sert simplement à stocker l'image.

    Je viens d'essayer de compiler avec VC, et ça marche :s (mis à part les quelques erreurs du aux fonctions de création de dll spécifiques à dev-c++). Franchement, je ne vois vraiment pas ce qui coince avec ce projet :s

  18. #18
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 15
    Points : 18
    Points
    18
    Par défaut
    donc en fait le probleme viendrait de dev?

  19. #19
    Membre à l'essai
    Inscrit en
    Juillet 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Faut croire :s

    C'est bizarre quand même :s

  20. #20
    Membre à l'essai
    Inscrit en
    Juillet 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Hum, j'ai rien dit en fait, problème sous VC6 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Init.obj : error LNK2001: unresolved external symbol "public: static struct SDL_Surface * CInit::screen" (?screen@CInit@@2PAUSDL_Surface@@A)

Discussions similaires

  1. Problème avec jointures multiples.
    Par Veritas5 dans le forum Développement
    Réponses: 3
    Dernier message: 05/06/2009, 15h42
  2. [JAXB] Après génération des classes problème avec AccessType
    Par GabriHell dans le forum Persistance des données
    Réponses: 3
    Dernier message: 17/09/2008, 11h52
  3. Problème avec la multiplication des images
    Par twix24 dans le forum Images
    Réponses: 4
    Dernier message: 12/12/2007, 09h07
  4. Problème avec onglets multiples
    Par moimael dans le forum VB.NET
    Réponses: 3
    Dernier message: 10/05/2007, 18h04
  5. [ClassLoader] Chargement dynamique d'une classe -> problème avec packages !
    Par ymerej dans le forum API standards et tierces
    Réponses: 9
    Dernier message: 31/05/2006, 21h37

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