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 :

dll et singleton


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    216
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2003
    Messages : 216
    Par défaut dll et singleton
    Hello.

    C'est la première fois que j'esseye de créer une DLL et biensur j'ai déjà une erreur

    Après avoir cherché pendant 2 heures pourquoi mon code source plantait uniquement quand il était sous forme de DLL, j'ai enfin trouvé mais je ne sais pas comment résoudre le problème :

    J'ai une classe "CMachinManager" qui est un singleton. J'ai une autre classe "A" qui accède à "CMachinManager" comme ceci : CMachinManager::instance().
    Les class du singleton, "CMachinManager" et "A" sont toutes compilé et mis dans une DLL.

    Ensuite si je cré un nouveau projet qui utilise la DLL que je vient de créer et que j'utilise CMachinManager::instance() dans ce projet et bien il ne va pas me retourner l'instance qui a déjà été créé dans la DLL par la classe "A" mais il va me retourner une nouvelle instance.

    Pourquoi me fait-il ça ? Surement parce que la mémoire entre la DLL et mon nouveau projet n'est pas partagé....
    Que faire pour résoudre le problème ?

    J'espère avoir été assez clair, merci

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    tu peut essayer un truc comme cela :
    http://www.ddj.com/cpp/199203083?pgno=3

  3. #3
    screetch
    Invité(e)
    Par défaut
    Je pense que ta classe est templatisée

    genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template<typename T>
    class Singleton
    {
      static T* instance;
    };
    le probleme est que ici ton instance est un static declaré dans un .h. Donc la variable statique va se retrouver dupliquées dans tous les modules liés (c'est a dire dans les dll et dans l'exe) et va etre locale a la dll ou a l'exe.

    Ma solution pour eviter ca a ete de creer un Singletonmanager, lequel enregistre les singleton dans un map dont laclé est typeid(T).name()

    ce singleton manager lui meme est un singleton mais l'instance est stockee dans un .cpp et donc est locale uniquement a la dll qui le contient. Ensuite pour retrouver l'instance :

    - si l'instance statique n'existe pas
    - regarder dans le dico et mettre ca dans le statique
    - renvoyer le statique

    pour creer :
    - mettre le resultat dans l'instance statique
    - ajouter l'instance dans le dico avec comme cle typeid(T).name()

    ce qui fait que la variable statique existe en plusieurs exemplaires mais ils pointent tous vers la meme instance. A moins de demander frequemment des singletons qui n'existent pas, tu iras le chercher dans le dico une fois pour chaque module et ensuite il sera stocké

    Je sais que le typeid(T).name() n'est pas portable mais c'est consistant de l'utiliser dans des dll sur la meme platforme avec le meme compilateur!

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    216
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2003
    Messages : 216
    Par défaut
    Merci beaucoup pour ta réponse mais j'ai quelques souci pour coder cette classe CSingletonManager !

    J'ai donc bien une classe singleton templatisée. Et voici en gros ma classe CSingletonManager (fait en vitesse)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class CSingletonManager
    {
    	public:
    		static void *getSingleton(std::string name);
     
    		static void addSingleton(std::string, void *);
    		static void removeSingleton(std::string);
     
    	private:
    		static std::map<std::string, void *> singletons;
    };
    Donc ma map contient un string qui est typeid(T).name() et un pointeur sur l'instance (void *)

    Voici la fonction getSingleton :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void *CSingletonManager::getSingleton(string name)
    {
    	map<string, void *>::iterator it = singletons.find(name);
    	if(it==singletons.end())
    		return NULL;
    	return singletons[name];
    }
    Et voici comment je fait pour aller rechercher mon instance :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    template<class T> inline T* CSingleton<T>::instance()
    {
    	if(!Instance) 
    	{
    		Instance = static_cast<T*>(CSingletonManager::getSingleton(typeid(T).name()));
    		if(!Instance)
    		{
    			Instance = new T;
    			CSingletonManager::addSingleton(typeid(T).name(), (void *)Instance);
    		}
    	}
     
    	return objectT;	
    }
    Si je compile ça normalement, ça va très bien mais si je fait un nouveau projet qui utilise la DLL, j'ai un problème au linkage :
    - J'ai des "undefined reference to CSingletonManager::addSingleton(std::string, void*)"
    - Et aussi des " undefined reference to `CSingletonManager::getSingleton(std::string)"

  5. #5
    screetch
    Invité(e)
    Par défaut
    il faut mettre des __declspec(dllimport/dllexport)

  6. #6
    Membre éclairé

    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 78
    Par défaut
    Ma remarque est peut être très conne, n'ayant jamais eu à faire à ceci ; mais pourquoi ne pas creer une fonction friend qui contient une instance static de la classe. Appeler cette fonction (CMachinManagerIntance() par exemple) à l'exterieur de la dll devrait fonctionner, non ?

    Je serais interressé de savoir pourquoi, si c'est non.

  7. #7
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    En même temps... dans ton header ou tu définis MaClass::instance() tu peux déclarer le template comme étant exporté (dllexport)... et réciproquement importé (dllimport) à l'utilisation.
    Le compilo va générer l'exportation de cette spécialisation du template, et le programme utilisateur va bien l'importer.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #ifdef MYLIBRARY_EXPORTS
        #define   MYLIBRARY_DECL        __declspec(dllexport)
        #define   MYLIBRARY_TEMPEXP  
    #else
        #define   MYLIBRARY_DECL        __declspec(dllimport)
        #define   MYLIBRARY_TEMPEXP  extern
    #endif
     
    class MaClass;
    MYLIBRARY_TEMPEXP template class MYLIBRARY_DECL Singleton<MaClass>;
    class MYLIBRARY_DECL MaClass : public Singleton<MaClass>
    {
    };
    Et voilà....

  8. #8
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par Aszarsha Voir le message
    Ma remarque est peut être très conne, n'ayant jamais eu à faire à ceci ; mais pourquoi ne pas creer une fonction friend qui contient une instance static de la classe. Appeler cette fonction (CMachinManagerIntance() par exemple) à l'exterieur de la dll devrait fonctionner, non ?

    Je serais interressé de savoir pourquoi, si c'est non.
    Je pense que ca doit être juste pour la "beauté" du template C++...

    Ceci marcherait tout autant (les probleme d'exportation de template en moins).
    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
     
    class MYLIBRARY_DECL MaClass
    {
       public:
          static MaClass& instance();
     
      protected:
          MaClass()
    };
     
    MaClass& MaClass::instance()
    {
       static MaClass _instance;
       return _instance;
    }

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

Discussions similaires

  1. Singleton dans dll ?
    Par KiwiJaune dans le forum VC++ .NET
    Réponses: 2
    Dernier message: 18/02/2010, 15h25
  2. Singleton dans une DLL
    Par mister3957 dans le forum C++
    Réponses: 9
    Dernier message: 24/03/2009, 10h01
  3. Singleton template partagé entre Dll et Exe
    Par eltrex dans le forum Langage
    Réponses: 1
    Dernier message: 07/08/2008, 12h13
  4. [DLL][Singleton] Doublon d'instance :(
    Par swirtel dans le forum C++Builder
    Réponses: 4
    Dernier message: 14/03/2007, 14h29
  5. Singleton sur plusieurs DLL
    Par 10_GOTO_10 dans le forum C++
    Réponses: 29
    Dernier message: 28/04/2006, 11h14

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