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 :

Singleton sur plusieurs DLL


Sujet :

C++

  1. #1
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut Singleton sur plusieurs DLL
    J'ai quelques données que je veux unique dans mon programme. Bon, pas de problème, je fais un singleton. Ca marche très bien... dans l'application principale.
    Parce que les DLL rattachées au programme ont leur propre segment de données. Donc une autre instance de mon singleton. J'ai donc un singleton multiple (vous me suivez ?). Pas top.
    Y a-t-il une façon de faire pour contourner ce problème ?

  2. #2
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Le singleton doit être présent, compilé, que dans une seule unité de compilation. Pour ce cas-ci, le mettre dans un DLL est peut-être la solution.

  3. #3
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut
    Le singleton ne doit être présent que dans une seule unité de compilation, on est d'accord. Par contre, la classe englobante (celle contenant la classe statique) peut être instanciée n'importe où dans l'appli (c'est à dire dans l'appli principale ou bien dans une des dll). Qui dit instanciation dit inclusion du .h, donc fatalement déclaration implicite d'une autre instance du singleton.

  4. #4
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Non, normalement le singleton n'est pas dans un fichier d'en-tête, il est déclaré static à un seul endroit, dans un fichier .cpp

  5. #5
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut
    Si je déclare le singleton dans le cpp (de la dll, par exemple), ça me fait un "Unresolved external" quand je compile l'application principale. Et réciproquement si je le met dans le cpp de l'appli.

  6. #6
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Ca veut dire que tu ne l'exportes pas alors que tu devrais.
    Si tu as 2 fois le fichier compilé dans ton projet, c'est normal que tu aies des multiples singletons. Il faut que ce singleton soit visible par tout le monde.

  7. #7
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut
    Si, il est bien exporté.
    Pour être clair: voilà les sources:

    ProjetDll:

    Unit1.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include <windows.h>
    #pragma argsused
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
      return 1;
    }
    Unit2.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
    //---------------------------------------------------------------------------
    #pragma hdrstop
    #include "Unit2.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    int _export MonSingleton::Data;
    extern "C" int _export GetData() {
      MonSingleton Instance;
      return Instance.Data;
    }
    extern "C" void _export SetData(int Data) {
      MonSingleton Instance;
      Instance.Data = Data;
    }
    Unit2.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #ifndef Unit2H
    #define Unit2H
    class MonSingleton {
    public:
      static int Data;
    };
    extern "C" int _export GetData();
    extern "C" void _export SetData(int Data);
    //---------------------------------------------------------------------------
    #endif
    Projet:

    Unit3.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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #include <vcl.h>
    #pragma hdrstop
    #include "Unit3.h"
    #include "Unit2.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
      : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::GetDataDllClick(TObject *Sender)
    {
      Edit1->Text = GetData();
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::SetDataDllClick(TObject *Sender)
    {
      SetData(Edit1->Text.ToInt());
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::GetDataSingletonClick(TObject *Sender)
    {
      MonSingleton Instance;
      Edit1->Text = Instance.Data;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::SetDataSingletonClick(TObject *Sender)
    {
      MonSingleton Instance;
      Instance.Data = Edit1->Text.ToInt();
    }
    Unit3.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
    #ifndef Unit3H
    #define Unit3H
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published: // Composants gérés par l'EDI
      TEdit *Edit1;
      TButton *GetDataDll;
      TButton *SetDataDll;
      TButton *GetDataSingleton;
      TButton *SetDataSingleton;
      void __fastcall GetDataDllClick(TObject *Sender);
      void __fastcall SetDataDllClick(TObject *Sender);
      void __fastcall GetDataSingletonClick(TObject *Sender);
      void __fastcall SetDataSingletonClick(TObject *Sender);
    private: // Déclarations de l'utilisateur
    public:  // Déclarations de l'utilisateur
      __fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif
    L'erreur:

    [Lieur Erreur] Unresolved external 'MonSingleton::Data' referenced from C:\TESTSINGLETON\UNIT3.OBJ

  8. #8
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Déjà, tu n'as besoin du
    Appelle directement la variable statique, elle est là pour ça.

    En même temps, c'est pas vraiment un singleton, mais passons

    L'erreur est simple, tu n'as aucun endroit où tu indiques où est stocké Data. Donc tu dois faire un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int MonSingleton::Data;
    dans un fichier .cpp.

  9. #9
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut
    Citation Envoyé par Miles
    Déjà, tu n'as besoin du
    Appelle directement la variable statique, elle est là pour ça.
    Heu... Ben si, c'est le principe du singleton, non ?

    Citation Envoyé par Miles
    En même temps, c'est pas vraiment un singleton, mais passons
    Bien sûr, j'ai simplifié à l'extrême le code

    Citation Envoyé par Miles
    L'erreur est simple, tu n'as aucun endroit où tu indiques où est stocké Data. Donc tu dois faire un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int MonSingleton::Data;
    dans un fichier .cpp.
    Ligne 6 de Unit2.cpp:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int _export MonSingleton::Data;

  10. #10
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Citation Envoyé par 10_GOTO_10
    Heu... Ben si, c'est le principe du singleton, non ?
    Non, pas vraiment. Le singleton, c'est une instance unique d'une classe. Là, c'est simplement une variable statique qu'on peut appeler par MonSingleton:ata directement... Pas besoin d'encapsuler dans une classe pour ça. C'est la classe qui devrait être unique s'il fallait un singleton, mais c'est sans doute pas nécessaire.
    Ligne 6 de Unit2.cpp:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int _export MonSingleton::Data;
    Oups, désolé pas fait gaffe
    C'est quoi _export ?

  11. #11
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut
    Citation Envoyé par Miles
    Non, pas vraiment. Le singleton, c'est une instance unique d'une classe. Là, c'est simplement une variable statique qu'on peut appeler par MonSingleton::Data directement... Pas besoin d'encapsuler dans une classe pour ça. C'est la classe qui devrait être unique s'il fallait un singleton, mais c'est sans doute pas nécessaire.
    Oui, tu as raison. Partons sur un singleton homologué avec pedigree, celui de wikipedia. Ca donne donc ceci:

    Unit2.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
    #ifndef Unit2H
    #define Unit2H
     
    template<typename T> class Singleton
    {
      public:
        static T& Instance()
        {
            static T theSingleInstance; // suppose que T a un constructeur par défaut
            return theSingleInstance;
        }
    };
     
    class MonSingleton : public Singleton<MonSingleton>
    {
        //...définir ici le reste de l'interface
    public:
        // C'est ce que je fais
        int Data;
    };
     
    extern "C" int _export GetData();
    extern "C" void _export SetData(int Data);
    //---------------------------------------------------------------------------
    #endif
    Unit2.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
    #pragma hdrstop
    #include "Unit2.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
     
    extern "C" int _export GetData() {
      MonSingleton Instance;
      return Instance.Instance().Data;
    }
     
    extern "C" void _export SetData(int Data) {
      MonSingleton Instance;
      Instance.Instance().Data = Data;
    }
    Unit3.h: pas modifié

    Unit3.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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #include <vcl.h>
    #pragma hdrstop
    #include "Unit3.h"
    #include "Unit2.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
     
    __fastcall TForm1::TForm1(TComponent* Owner)
      : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------
    ------
     
    void __fastcall TForm1::GetDataDllClick(TObject *Sender)
    {
      Edit1->Text = GetData();
    }
    //---------------------------------------------------------------------------
     
    void __fastcall TForm1::SetDataDllClick(TObject *Sender)
    {
      SetData(Edit1->Text.ToInt());
    }
    //---------------------------------------------------------------------------
     
    void __fastcall TForm1::GetDataSingletonClick(TObject *Sender)
    {
      MonSingleton Instance;
      Edit1->Text = Instance.Instance().Data;
    }
    //---------------------------------------------------------------------------
     
    void __fastcall TForm1::SetDataSingletonClick(TObject *Sender)
    {
      MonSingleton Instance;
      Instance.Instance().Data = Edit1->Text.ToInt();
    }
    Qui ne marche toujours pas (ça se compile, mais j'ai un singleton multiple).

  12. #12
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Bon, comme toujours, ton singleton est faux, pour y accéder tu dois faire comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonSingleton::Instance()
    Si tu crées un MonSingleton, tu ne peux avoir de singleton, puisque tu peux les créer comme tu veux.

    Tu donnes quoi comme header aux autres fichiers cpp de tes autres programmes ?

  13. #13
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut
    Citation Envoyé par Miles
    Bon, comme toujours, ton singleton est faux, pour y accéder tu dois faire comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonSingleton::Instance()
    Citation Envoyé par Mon compilo
    [C++ Erreur] Unit2.cpp(10): E2108 Utilisation impropre de typedef 'MonSingleton'
    [C++ Erreur] Unit2.cpp(14): E2108 Utilisation impropre de typedef 'MonSingleton'
    Pourrais-tu expliciter ?

    Citation Envoyé par Miles
    Si tu crées un MonSingleton, tu ne peux avoir de singleton, puisque tu peux les créer comme tu veux.
    Arrête moi si je dis une bêtise, mais le principe du singleton, c'est quand même d'accéder à une classe unique à partir d'instances multiples de la classe "enveloppante", non ? Sinon, il n'y aurait aucun avantage par rapport à une variable globale.

    Citation Envoyé par Miles
    Tu donnes quoi comme header aux autres fichiers cpp de tes autres programmes ?
    Je n'ai pas d'autres programmes. Pour ce test, je n'ai que le projet ProjetDll qui comprend Unit1.cpp et Unit2.cpp, et l'application principale Projet qui comprend Unit3.cpp (lequel inclue Unit2.h), et ProjetDll.lib pour les exports.

  14. #14
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Oui, tu dis une bêtise
    Le singleton, c'est une seule instance d'une classe et impossibilité d'en créer une autre. L'avantage par rapport à une variable globale est multiple, je te laisse explorer ce tutoriel http://smeric.developpez.com/java/uml/singleton/
    C'est du Java, mais le principe reste identique.

    C'est bizarre le coup des typedef, surtout que tu n'as l'air d'en avoir dans ton code...

    Le doublon du singleton, c'est sans doute dû à ton en-tête Unit2.hpp en trop

  15. #15
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut
    Citation Envoyé par Miles
    Le singleton, c'est une seule instance d'une classe et impossibilité d'en créer une autre.
    Citation Envoyé par Miles
    Si tu crées un MonSingleton, tu ne peux avoir de singleton, puisque tu peux les créer comme tu veux.
    C'est contradictoire, tout ça. Si le singleton interdit de créer une autre instance, j'aurais pas dû pouvoir en créer "comme je veux".


    Citation Envoyé par Miles
    L'avantage par rapport à une variable globale est multiple, je te laisse explorer ce tutoriel
    Je n'en doute pas. Oui, j'ai déjà lu ce tutoriel (j'ai commencé par ça avant de poster, comme tout foromeur qui se respecte).

    Citation Envoyé par Miles
    Le doublon du singleton, c'est sans doute dû à ton en-tête Unit2.hpp en trop
    En trop ? Il faut bien la déclarer quelque part, cette classe singleton ?

    Bon, j'ai l'impression que ce post tourne en rond, voire dérive en troll, ce que je ne voudrais pas. Y a-t-il quelque part un exemple de singleton (de variable globale, ou de n'importe quoi qui soit unique) entre deux dll, ou entre un programme et une dll ? Tous les exemples que j'ai vu sur google se contentent de la définition (en général toujours la même, celle que j'ai utilisée).

  16. #16
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Citation Envoyé par 10_GOTO_10
    C'est contradictoire, tout ça. Si le singleton interdit de créer une autre instance, j'aurais pas dû pouvoir en créer "comme je veux".
    Eh oui, c'est pour ça que ce n'est pas un singleton, ce que tu as fait.
    Je n'en doute pas. Oui, j'ai déjà lu ce tutoriel (j'ai commencé par ça avant de poster, comme tout foromeur qui se respecte).

    En trop ? Il faut bien la déclarer quelque part, cette classe singleton ?

    Bon, j'ai l'impression que ce post tourne en rond, voire dérive en troll, ce que je ne voudrais pas. Y a-t-il quelque part un exemple de singleton (de variable globale, ou de n'importe quoi qui soit unique) entre deux dll, ou entre un programme et une dll ? Tous les exemples que j'ai vu sur google se contentent de la définition (en général toujours la même, celle que j'ai utilisée).
    Comment constates-tu la présence de 2 singletons ?

  17. #17
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut
    Citation Envoyé par Miles
    Comment constates-tu la présence de 2 singletons ?
    C'est simple, dans l'appli principale j'ai une boîte d'édition et quatre boutons. Deux boutons SetData et deux boutons GetData (voir Unit3.cpp). L'un des deux boutons appelle directement le singleton, l'autre appelle une fonction de la dll qui appelle ce même (enfin, j'aimerais bien) singleton.

    1. Je met "1" dans l'edit et je clique sur SetDataSingleton
    2. Je met "2" dans l'edit et je clique sur SetDataDll
    3. Je clique sur GetDataSingleton => ça me remet "1" dans l'edit
    4. Je clique sur GetDataDll => ça me remet "2" dans l'edit
    L'étape 3 prouve que le singleton marche à l'intérieur d'une même entité (même si j'ai deux instances différentes dans les méthodes GetData et SetData). L'étape 4 met en évidence qu'il y a deux singletons, celui accessible du programme principal, et celui accessible depuis la dll.

  18. #18
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Tu pourrais juste redonner ton code mis à jour ? Il n'y a pas l'air d'y avoir quelque part la déclaration de ta variable statique, donc si tu pouvais le remettre pour qu'on y voit un peu plus clair

  19. #19
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut
    Pas de Problème.

    1) Donc, un projet dll normal, monothread, c++ qui s'appelle ProjetDll et qui contient Unit1.cpp et Unit2.cpp (donc, par inclusion Unit2.h):

    Unit1.cpp:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include <windows.h>
     
    #pragma argsused
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
      return 1;
    }
    Unit2.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
    #pragma hdrstop
    #include "Unit2.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
     
    extern "C" int _export GetData() {
      MonSingleton InstanceLocale;
      return InstanceLocale.Instance().Data;
    }
     
    extern "C" void _export SetData(int Data) {
      MonSingleton InstanceLocale;
      InstanceLocale.Instance().Data = Data;
    }
    Unit2.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
    #ifndef Unit2H
    #define Unit2H
     
    template<typename T> class Singleton
    {
      public:
        static T& Instance()
        {
            static T theSingleInstance; // suppose que T a un constructeur par défaut
            return theSingleInstance;
        }
    };
     
    class MonSingleton : public Singleton<MonSingleton>
    {
        //...définir ici le reste de l'interface
    public:
        // C'est ce que je fais
        int Data;
    };
     
    extern "C" int _export GetData();
    extern "C" void _export SetData(int Data);
    //---------------------------------------------------------------------------
    #endif
    Ensuite, un projet window classique avec une fenêtre, quatre boutons et une boîte d'édition, nommé Projet, contenant Unit3.cpp (et, par inclusion, Unit2.h et Unit3.h):

    Unit3.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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #include <vcl.h>
    #pragma hdrstop
    #include "Unit3.h"
    #include "Unit2.h"
    //---------------------------------------------------------------------------
     
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
     
    __fastcall TForm1::TForm1(TComponent* Owner)
      : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
     
    void __fastcall TForm1::GetDataDllClick(TObject *Sender)
    {
      Edit1->Text = GetData();
    }
    //---------------------------------------------------------------------------
     
    void __fastcall TForm1::SetDataDllClick(TObject *Sender)
    {
      SetData(Edit1->Text.ToInt());
    }
    //---------------------------------------------------------------------------
     
    void __fastcall TForm1::GetDataSingletonClick(TObject *Sender)
    {
      MonSingleton InstanceLocale;
      Edit1->Text = InstanceLocale.Instance().Data;
    }
    //---------------------------------------------------------------------------
     
    void __fastcall TForm1::SetDataSingletonClick(TObject *Sender)
    {
      MonSingleton InstanceLocale;
      InstanceLocale.Instance().Data = Edit1->Text.ToInt();
    }
    Unit3.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
    29
    30
    #ifndef Unit3H
    #define Unit3H
     
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    //---------------------------------------------------------------------------
     
    class TForm1 : public TForm
    {
    __published: // Composants gérés par l'EDI
      TEdit *Edit1;
      TButton *GetDataDll;
      TButton *SetDataDll;
      TButton *GetDataSingleton;
      TButton *SetDataSingleton;
      void __fastcall GetDataDllClick(TObject *Sender);
      void __fastcall SetDataDllClick(TObject *Sender);
      void __fastcall GetDataSingletonClick(TObject *Sender);
      void __fastcall SetDataSingletonClick(TObject *Sender);
    private: // Déclarations de l'utilisateur
    public:  // Déclarations de l'utilisateur
      __fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif
    Pour compiler sous Borland, voilà aussi le dfm:

    Unit3.dfm

    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
    object Form1: TForm1
      Left = 223
      Top = 165
      Width = 326
      Height = 117
      Caption = 'Form1'
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'MS Sans Serif'
      Font.Style = []
      OldCreateOrder = False
      PixelsPerInch = 96
      TextHeight = 13
      object Edit1: TEdit
        Left = 12
        Top = 18
        Width = 55
        Height = 21
        TabOrder = 0
      end
      object GetDataDll: TButton
        Left = 84
        Top = 18
        Width = 109
        Height = 22
        Caption = 'Get data / dll'
        TabOrder = 1
        OnClick = GetDataDllClick
      end
      object SetDataDll: TButton
        Left = 84
        Top = 51
        Width = 109
        Height = 22
        Caption = 'Set data / dll'
        TabOrder = 2
        OnClick = SetDataDllClick
      end
      object GetDataSingleton: TButton
        Left = 204
        Top = 18
        Width = 109
        Height = 22
        Caption = 'Get data / singleton'
        TabOrder = 3
        OnClick = GetDataSingletonClick
      end
      object SetDataSingleton: TButton
        Left = 204
        Top = 51
        Width = 109
        Height = 22
        Caption = 'Set data / singleton'
        TabOrder = 4
        OnClick = SetDataSingletonClick
      end
    end
    Et c'est ce code qui a le comportement de mon précédent post.

  20. #20
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    OK, c'est ce que je pensais. La raison provient sans doute de l'inline du singleton dans unit2.hpp.
    Vire la classe template en mettant ce qu'il faut dans ta classe, mais ne mets le corps de la fonction que dans unit2.cpp. Tu vois ce que je veux dire ? Ca pourra peut-être marcher.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. deploiment de code sur plusieurs machines et problème avec une dll
    Par eric1708 dans le forum GTK+ avec C & C++
    Réponses: 7
    Dernier message: 17/12/2013, 08h55
  2. Faire une DLL répartie sur plusieurs fichiers
    Par guda dans le forum VB.NET
    Réponses: 3
    Dernier message: 06/08/2013, 10h12
  3. Réponses: 2
    Dernier message: 24/04/2012, 13h47
  4. plusieurs questions sur les Dll
    Par mnaulet dans le forum Windows
    Réponses: 4
    Dernier message: 07/08/2006, 08h39
  5. [CR] Groupement dynamique sur plusieurs champs paramètrés
    Par CDRIK dans le forum SAP Crystal Reports
    Réponses: 8
    Dernier message: 07/06/2004, 17h55

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