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 :

[YES::ENGINE] Problème Singleton


Sujet :

C++

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 58
    Points : 44
    Points
    44
    Par défaut [YES::ENGINE] Problème Singleton
    Bonjour,

    Je viens vers vous suite à un problème que je rencontre avec un projet suite à la série "Réalisation d'un moteur 3D en C++".

    J'ai voulu réaliser ce tuto pour mon moteur en partant du tous début pour mieux comprendre et sans compiler directement les sources du tuto.

    J'ai donc commencer à créer un projet dll qui contient le moteur et un second projet win32 pour tester l'import de la dll.

    Tous se passe bien pour l'export mais je rencontre un problème au niveau je pense de l'import.

    voici l'erreur que je reçois :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Erreur	3	error LNK2019: symbole externe non résolu "public: __thiscall C_Test::C_Test(void)" (??0C_Test@@QAE@XZ) référencé dans la fonction "public: static class C_Test & __cdecl SilverEngine::C_Singleton<class C_Test>::Instance(void)" (?Instance@?$C_Singleton@VC_Test@@@SilverEngine@@SAAAVC_Test@@XZ)	C:\Users\ksta\Desktop\DLL\Projets\TestDLL\Main.obj	TestDLL
    voici le code de ma classe C_Test.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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    #include <Core/C_IWin32Application.h>
    #include <Renderers/C_IRenderer.h>
    #include <Utilities/Debug/Loggers/C_ILogger.h>
    #include <Utilities/Debug/Loggers/C_LoggerFile.h>
    #include <windows.h>
    #include <string>
     
     
    using namespace SilverEngine;
     
    class C_Test : public C_IWin32Application, public C_Singleton<C_Test> {
    	friend class C_Singleton<C_Test>;
    	public:
    		C_Test();
    		~C_Test();
     
    		void initialize();
    		void createWindow(int p_posX, int p_posY, int p_width, int p_height);
    		void draw();
     
    		LRESULT CALLBACK WindowProc(HWND Hwnd, UINT Message, WPARAM WParam, LPARAM LParam);
    		static LRESULT CALLBACK GlobalWindowProc(HWND Hwnd, UINT Message, WPARAM WParam, LPARAM LParam);  
     
    		void start();
    		void stop();
     
    	};
    Et voici le code de C_Test.cpp (j'ai enlever le code dans les fonction pour pas que cela agrandisse le message):
    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
     
    #include "C_Test.h"
     
     
    	C_Test::C_Test(){}
     
    	C_Test::~C_Test(){}
     
     
    	void C_Test::initialize(){
     
    	}
     
     
    	void C_Test::createWindow(int p_posX, int p_posY, int p_width, int p_height){
     
    	}
     
     
    	void C_Test::draw(){
     
    	}
     
    	LRESULT CALLBACK C_Test::GlobalWindowProc(HWND p_hwnd, UINT p_message, WPARAM p_wParam, LPARAM p_lParam){
     
    	}
     
     
    	LRESULT CALLBACK C_Test::WindowProc(HWND p_hwnd, UINT p_message, WPARAM p_wParam, LPARAM p_lParam){
     
    	}
     
           void C_Test::start(){
     
    	}
     
     
    	void C_Test::stop(){
     
     
    	}
    Et la dernière la class C_Singleton qui est la même que le tuto :

    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
     
    #pragma once
     
    #include <cstdlib>
     
    /**
    * \namespace SilverEngine
    */
    namespace SilverEngine{
    	/**
            *       \class   C_Singleton
            */
    	template <class T>
    	class C_Singleton{
    	/**
            * \publicsection
            */
    	public:
     
    		//----------------------------------------------------------------
    		// Renvoie l'instance unique de la classe
    		//----------------------------------------------------------------
    		static T& Instance(){
    			if (!Inst)
    				Inst = new T;
     
    			return *Inst;
    		}
     
     
    		//----------------------------------------------------------------
    		// Renvoie le pointeur de l'instance unique de la classe
    		//----------------------------------------------------------------
    		static T* InstancePtr(){
    			if (!Inst)
    				Inst = new T;
     
    			return Inst;
    		}
     
    		//----------------------------------------------------------------
    		// Détruit l'instance unique de la classe
    		//----------------------------------------------------------------
    		static void Destroy(){
    			delete Inst;
    			Inst = NULL;
    		}
    	/**
            * \protectedsection
            */
    	protected:
    		////////////////////////////////
    		//	CONSTRUCTORS / DESTRUCTOR
    		C_Singleton() {}
    		~C_Singleton() {}
    	/**
            * \privatesection
            */
    	private:
     
    		//----------------------------------------------------------------
    		// Données membres
    		//----------------------------------------------------------------
    		static T* Inst; // Instance de la classe
     
    		//----------------------------------------------------------------
    		// Copie interdite
    		//----------------------------------------------------------------
    		C_Singleton(C_Singleton&);
    		void operator =(C_Singleton&);
    	};
     
    	// Initialisation du singleton
    	template <class T> T* C_Singleton<T>::Inst = NULL;
     
     
    }
    Dans les propriétées du projet TestDLL j'ai bien référencer le projet du moteur et également rajouter les dépendances supplémentaire vers le dossier du moteur.

    Est-ce que quelqu'un serait d’où sa pourrai venir et/ou si il à rencontrer le même problème?

    je vous remercie d'avance.

  2. #2
    Membre éclairé

    Homme Profil pro
    ingénieur de recherche
    Inscrit en
    Mars 2011
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : ingénieur de recherche
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2011
    Messages : 103
    Points : 864
    Points
    864
    Par défaut
    Bonjour,

    Pour moi ton héritage est insoluble: Tu hérite la classe c_test d'un template de la classe c_test elle même.

    Or pour définir un héritage il faut que le compilateur connaisse la classe mère en entier, de même pour la construction d'un template il faut que le compilateur connaisse le type complet de l'argument du template.

    Ainsi le compilateur essai de définir c_type, pour cela il essai de définir le template mère. Celui-ci a besoin de connaitre c_type, alors il essaie de définir c_type. C'est une boucle infinie.

    C'est un peut comme une classe héritée d'elle même

    d'où le "symbole externe non résolu".
    Mes tutoriels avancés sur la triangulation par filet à surface et sur les octree - N'hésitez pas à consulter les tutoriels et FAQ 2D/3D/jeux.

  3. #3
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Normalement, ca marche, et même, c'est assez courant pour avoir un nom: le CRTP pour Curiously Recurring Template Pattern.
    Nous avons une entrée dans la faq, a ce sujet.

    Le problème est une erreur de link, c'est à dire d'une fonction finalement non définie.
    Vu que le constructeur est publique, as-tu essayé de définir une variable de ce type? (quitte à supprimer temporairement l'héritage de C_singleton)

    Vérifie qu'il n'y a pas un namespace qui traine.
    Supprime ton horrible "using namespace" de ton .h (ou mets le dans la classe elle-même).

    Pourquoi as-tu besoin de rendre donner singleton comme friend de la classe?
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  4. #4
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    Salut!
    Pour moi ton héritage est insoluble: Tu hérite la classe c_test d'un template de la classe c_test elle même.

    Or pour définir un héritage il faut que le compilateur connaisse la classe mère en entier, de même pour la construction d'un template il faut que le compilateur connaisse le type complet de l'argument du template.

    Ainsi le compilateur essai de définir c_type, pour cela il essai de définir le template mère. Celui-ci a besoin de connaitre c_type, alors il essaie de définir c_type. C'est une boucle infinie.

    C'est un peut comme une classe héritée d'elle même
    Non, comme le dit leternel, c'est un idiome courant qui fonctionne très bien class A: public B<A>{}; CRTP. Utile pour les singletons, également les incopiables etc...

    Ca ne fonctionne pas car tu utilises une DLL. Donc tu dois utiliser les mots clés qui vont te permettre d'exporter ton code. ( Tu observeras que le taille de ta DLL n'est pas la même avec ou sans lorsque tu compilera en export )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #ifdef DLL_EXPORTS
    #define DLL_API __declspec(dllexport)
    #else
    #define DLL_API __declspec(dllimport)
    #endif
    Tu dois maintenant exporter ta classe dans la DLL et pouvoir l'importer dans ton code client.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class DLL_API C_Test {};
    Lorsque tu compile ta DLL tu défini DLL_EXPORTS, lorsque tu l'utilise tu ne définis rien... Tu garde le link dans tes configurations!


    cf :
    https://msdn.microsoft.com/fr-fr/library/ms235636.aspx
    https://msdn.microsoft.com/fr-fr/library/81h27t8c.aspx
    Homer J. Simpson


  5. #5
    Membre éclairé

    Homme Profil pro
    ingénieur de recherche
    Inscrit en
    Mars 2011
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : ingénieur de recherche
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2011
    Messages : 103
    Points : 864
    Points
    864
    Par défaut
    Citation Envoyé par Astraya Voir le message
    Non, comme le dit leternel, c'est un idiome courant qui fonctionne très bien class A: public B<A>{}; CRTP. Utile pour les singletons, également les incopiables etc...
    Oups, désolé alors. Je me coucherais moins bête ce soir.
    Mes tutoriels avancés sur la triangulation par filet à surface et sur les octree - N'hésitez pas à consulter les tutoriels et FAQ 2D/3D/jeux.

  6. #6
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 58
    Points : 44
    Points
    44
    Par défaut
    Salut,

    Désoler du retard.

    @PierroVsf: en effet c'est possible je l'est découvert justement avec ce tuto et je trouve sa vraiment bien pour les Singleton.

    @Astraya: En effet j'ai bien le fichier Export.cpp qui contient l'export mais j'avoue que j'ai pas du tous penser à l'exporter

    Je suis nouveau dans les DLL et c'est vrai que je ne comprend pas tous.

    En tous cas cela marche avec l'export

    Je vous remercie de votre aide

    Je vais approfondir les DLL

    encore merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Yes::Engine] problème de compilation avec mingw et <cmath>
    Par jo-leptipois dans le forum Moteurs 3D
    Réponses: 1
    Dernier message: 04/09/2013, 08h06
  2. [YES::ENGINE]:problème de compilation visual c++ 2005
    Par starkyetHutch dans le forum Moteurs 3D
    Réponses: 2
    Dernier message: 01/02/2008, 17h06
  3. [YES::ENGINE]Problème d'exportation dans une dll
    Par trecks dans le forum Moteurs 3D
    Réponses: 2
    Dernier message: 30/11/2007, 08h26
  4. [Yes::Engine] Problèmes d'exécution
    Par Kajisan dans le forum Moteurs 3D
    Réponses: 5
    Dernier message: 12/06/2007, 14h18
  5. Réponses: 11
    Dernier message: 21/09/2005, 03h56

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