Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Singleton : *Learn mode on*

3 réponses
Avatar
Geoffrey
Bonjour a tous,
voila j'aimerai une petite explication sur le probleme suivant.

j'ai une dll DLLA qui a un object SingletonA

ce singleton est donc créé au cours de l'execution de A par l'appel a une
methode statique

si la DLLA charge une DLLB, et que dans la DLLB j'appelle mon singleton dans
A -> SingletonA::Instance()
le comportement n'est pas celui que j'attendais.
Et la c'est un peu brouillon dans mon esprit ...

En fait, la methode statique executé dans le contexte DLLB ne connait pas
l'instance créé dans DLLA et rapelle donc le constructeur de SingletonA (
effectivement ca parait logique ) mais ce constructeur est quand a lui
executé dans le contexte de A ( pourquoi ? ) ou l'instance existe deja.

Quand a moi je voudrais etre capable d'appeler l'instance de cette classe
SingletonA definie dans DLLA depuis DLLB ?? Est ce que c'est possible, et ou
est ce que je me trompe ?

Merci de vos reponses.
Si besoin je vais essayer d'illustrer ceci avec du code ...


la class Singleton est de ce type :

template< typename T> class Singleton
{
protected:
static T* mSingleton;

public:
Singleton()
{
assert( mSingleton == NULL ) // Heureusement que j'ai cette
assertion pour me rendre compte du probleme !
}
~Singleton()
{
mSingleton = NULL;
}

static T& Instance()
{
if ( mSingleton == NULL )
mSingleton = new T;

assert( mSingleton != NULL );
return (*mSingleton);
}

static void Destroy()
{
if ( mSingleton != NULL )
{
delete mSingleton;
mSingleton = NULL;
}
}
};

3 réponses

Avatar
Fabien LE LEZ
On Wed, 19 Oct 2005 12:14:25 +0200, "Geoffrey" :

j'ai une dll DLLA qui a un object SingletonA

ce singleton est donc créé au cours de l'execution de A par l'appel a une
methode statique

si la DLLA charge une DLLB, et que dans la DLLB j'appelle mon singleton dans
A -> SingletonA::Instance()

static T* mSingleton;


Ceci est une déclaration de variable (membre).
Normalement, tu dois avoir la définition qui va avec, dans un .cpp et
un seul. Typiquement :

static T* Singleton::mSingleton= NULL;

Seulement voilà, ta classe est une classe template, du coup la
définition en question se trouve sans doute dans un .h. Le linker s'en
tire sans ajout de paracétamol quand tu te contentes d'un exécutable,
mais dans le cas qui nous préoccupe, tu en as trois (un .exe et deux
.dll, qui sont en fait, à peu de chose près, des .exe).

Honnêtement, je ne pense pas être capable de comprendre la mécanique
interne de ce machin. Par contre, je peux te proposer une solution :
dé-templatiser le singleton, et mettre le pointeur dans un .cpp.
Ainsi, tu sauras exactement quelle DLL a le pointeur.



// machin.h

class Machin // un singleton
{
public:
friend Machin* GetInstanceMachin();

private:
Machin();
Machin (Machin const&);
void operator= (Machin);
};


// machin.cpp

static Machin* ptr_instance_Machin= 0;

Machin* GetInstanceMachin()
{
if (ptr_instance_Machin == 0)
{
ptr_instance_Machin= new Machin;
}
return ptr_instance_Machin;
}

Oui, je sais, c'est pas très idiomatique, mais c'est plus encapsulé,
et ça permet de s'y retrouver plus facilement quand, comme moi, on n'a
pas les idées claires sur le sujet : une DLL (et une seule) contient
le pointeur Machin*, et cette DLL exporte la fonction
GetInstanceMachin(). C'est clair, net et précis.

Avatar
Geoffrey
"Fabien LE LEZ" a écrit dans le message de news:

On Wed, 19 Oct 2005 12:14:25 +0200, "Geoffrey" :

j'ai une dll DLLA qui a un object SingletonA

ce singleton est donc créé au cours de l'execution de A par l'appel a une
methode statique

si la DLLA charge une DLLB, et que dans la DLLB j'appelle mon singleton
dans
A -> SingletonA::Instance()

static T* mSingleton;


Ceci est une déclaration de variable (membre).
Normalement, tu dois avoir la définition qui va avec, dans un .cpp et
un seul. Typiquement :

static T* Singleton::mSingleton= NULL;


oui excuse moi dans ma classe Singleton a la suite j'ai bien
l'initialisation du membre static mSingleton a NULL comme suis :
template <class T> T* Singleton<T>::mSingleton = NULL;

tout ca se trouve en effet dans le fichier en-tête

Seulement voilà, ta classe est une classe template, du coup la
définition en question se trouve sans doute dans un .h. Le linker s'en
tire sans ajout de paracétamol quand tu te contentes d'un exécutable,
mais dans le cas qui nous préoccupe, tu en as trois (un .exe et deux
.dll, qui sont en fait, à peu de chose près, des .exe).

Honnêtement, je ne pense pas être capable de comprendre la mécanique
interne de ce machin. Par contre, je peux te proposer une solution :
dé-templatiser le singleton, et mettre le pointeur dans un .cpp.
Ainsi, tu sauras exactement quelle DLL a le pointeur.



// machin.h

class Machin // un singleton
{
public:
friend Machin* GetInstanceMachin();

private:
Machin();
Machin (Machin const&);
void operator= (Machin);
};


// machin.cpp

static Machin* ptr_instance_Machin= 0;

Machin* GetInstanceMachin()
{
if (ptr_instance_Machin == 0)
{
ptr_instance_Machin= new Machin;
}
return ptr_instance_Machin;
}

Oui, je sais, c'est pas très idiomatique, mais c'est plus encapsulé,
et ça permet de s'y retrouver plus facilement quand, comme moi, on n'a
pas les idées claires sur le sujet : une DLL (et une seule) contient
le pointeur Machin*, et cette DLL exporte la fonction
GetInstanceMachin(). C'est clair, net et précis.



En fait, j'ai oublié cette infos,
ma DLLA qui contient donc ma classe declare comme suis "class
__declspec(dllexport) SingletonA : public Singleton<SingletonA>"

la classe est donc exportée ??
dites moi si j'ai bien compris ( desolé, j'espere que ce que j'ecris ne va
pas etre trop confus )

ma DLLB quand a elle est liée a DLLA.lib et inclus le fichier SingletonA.h
=> je peux donc utiliser l'objet SingletonA definie dans DLLA a partir de
DLLB ??

maintenant quand est il des membres statiques de SingletonA ??? Sont ils
egalement exportés ??
Est ce que ca peut etre un probleme d'exportation des membres statiques ?


Avatar
Geoffrey
autant pour moi, je devrai me coucher plus tot egalement ...

j'ai juste deconné avec mes symboles d'export/import ...
C'est la faute au copié/collé, je suis derangé, et j'oublie de modifier !
desolé du derangement
;))