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 :

pointeur extern et DLL


Sujet :

C++

  1. #1
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut pointeur extern et DLL
    Bonjour,
    j'ai un soucis et je crois savoir d'où il vient. Je voudrais confirmation.

    J'ai, dans une DLL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Base;
     
    class Derivee : public Base
    {
    };
     
    Derivee * uniqueInstance = NULL;
     
    Base * createInstance()
    {
      uniqueInstance = new Derivee();
      return uniqueInstance;
    }
    Puis une application qui appelle createInstance() et qui interagit avec l'interface Base.

    Pour plus de comodité, j'avais écrit dans cette DLL partout où j'avais besoin de mon instance :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    extern Derivee * uniqueInstance;
    Et je m'en servais pour interroger des propriétés de l'instance.

    Seulement voila, l'application peut charger plusieurs fois ma DLL et j'ai l'impression que les pointeurs extern des deux DLL pointent vers le même objet. Alors que deux new ont été appellés.

    Donc ma question : un pointeur extern dans une DLL est-il partagé pour toute les DLL de l'appli ?

  2. #2
    Membre confirmé Avatar de 5:35pm
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    201
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2006
    Messages : 201
    Par défaut
    l'utilisation d'extern n'est pas la bonne approche.
    extern sert a dire au compilo "ceci est definit dans un autre module"
    dans ton cas declare plutot uniqueInstance en static (comme tout singleton)
    et utilise __declspec( dllexport ) pour partager ton singleton avec ton client.

    fichier .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     class __declspec( dllexport ) Derivee : public Base
    {
    public:
      static Base* createInstance();
    private:
      static  Derivee * uniqueInstance;
    };
     
    Derivee * Derivee::uniqueInstance = NULL;
    .cpp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Base * Derivee::createInstance()
    {
      uniqueInstance = new Derivee();
      return uniqueInstance;
    }

  3. #3
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Oui je peux utiliser un singleton, mais j'avais pensé à extern pour ne pas avoir à sortir l'artillerie lourde. (je sais que mon pointeur est toujours non null et aucune chance qu'il puisse avoir une autre instance.)
    Mais la solution est, comme tu le dis, de placer le pointeur en static dans la classe, quitte à le mettre public après.

    extern sert a dire au compilo "ceci est definit dans un autre module"
    Ben c'etait un peu ça l'idée. De dire que le pointeur se trouve dans une autre unité de compil (autre cpp). Mais visiblement si je charge deux fois ma DLL ça ne marche plus.

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    Seulement voila, l'application peut charger plusieurs fois ma DLL ...
    Comment c'est possible de charger 2 fois (ou plus) la même DLL ? Ou alors elle est déchargée entre temps ?
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  5. #5
    Membre confirmé Avatar de 5:35pm
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    201
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2006
    Messages : 201
    Par défaut
    en effet une dll ne marche pas comme une instance en memoire

  6. #6
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Alors ce qui doit se passer (je n'ai pas du tout accès au code et je ne m'y connais pas trop en DLL) c'est que l'appli charge une seule fois la DLL mais appelle deux fois la méthode GetInstance(). Dans ce cas là je suis dans la m.... car même un singleton ne fonctionnera pas.

    Je vais devoir passer un pointeur vers mon objet dans les contructeurs des classes qui en ont besoin... faich

  7. #7
    doccpu
    Invité(e)
    Par défaut
    Citation Envoyé par 5:35pm Voir le message
    l'utilisation d'extern n'est pas la bonne approche.
    extern sert a dire au compilo "ceci est definit dans un autre module"
    dans ton cas declare plutot uniqueInstance en static (comme tout singleton)
    et utilise __declspec( dllexport ) pour partager ton singleton avec ton client.

    fichier .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     class __declspec( dllexport ) Derivee : public Base
    {
    public:
      static Base* createInstance();
    private:
      static  Derivee * uniqueInstance;
    };
     
    Derivee * Derivee::uniqueInstance = NULL;
    .cpp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Base * Derivee::createInstance()
    {
      uniqueInstance = new Derivee();
      return uniqueInstance;
    }
    Très bonne idée que de faire une dll en bonne et due forme mais à quoi cela sert il si l'on ne corrige pas, par la même occasion, les fuites de mémoires qu'engendre plusieurs appels à createInstance() ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Base * Derivee::createInstance()
    {
         if(!uniqueInstance)
         {
              uniqueInstance = new Derivee();
         }
         return (Base*) uniqueInstance;
    }
    sans oublier la destruction de l'instance :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void Derivee::destroyInstance()
    {
         if(uniqueInstance)
         {
              delete uniqueInstance;
         }
         uniqueInstance = NULL;
    }

  8. #8
    doccpu
    Invité(e)
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    Oui je peux utiliser un singleton, mais j'avais pensé à extern pour ne pas avoir à sortir l'artillerie lourde. (je sais que mon pointeur est toujours non null et aucune chance qu'il puisse avoir une autre instance.)
    Mais la solution est, comme tu le dis, de placer le pointeur en static dans la classe, quitte à le mettre public après.



    Ben c'etait un peu ça l'idée. De dire que le pointeur se trouve dans une autre unité de compil (autre cpp). Mais visiblement si je charge deux fois ma DLL ça ne marche plus.
    Si ! Il y a plusieurs instances de Derivee(1 par appels à createInstance) mais seulement 1 seul pointeur ! Le fait qu'il soit non null ne change rien au problème. Tu à des fuites de mémoires !

    Les unités de compils ne sont pas des .cpp mais des .o et si tu a le cpp d'origine fais les modifs que l'on t'a prescrites et vois si tu peux pas directement inclure le cpp a ton projet.

  9. #9
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Citation Envoyé par doccpu Voir le message
    ou tu demande a celui qui a fait la dll de faire son job correctement !
    He, doucement.
    Ne dis pas ça, j'ai fait cette DLL dans le cadre de mes loisirs et il se trouve que c'est la premiere fois que je suis amené à en faire une moi même.

    L'application mère est un logiciel commercial qui dispose d'un sdk minimum pour fournir des DLL.

    Dans ce sdk, il y a en gros une interface nommée Base on va dire et une méthode (non membre) createInstance() qui renvoie un pointeur vers une Base.

    Jusque la pas de soucis.

    Maintenant j'écarte totalement l'idée d'une instance unique type singleton ou même pointeur extern car je viens de comprendre le fonctionnement réel.

    J'étais parti dans l'idée que la dll se chargeait n fois, tout comme on pourrait lancer plusieurs instances d'un même exe.

    Je vois mon erreur, je corrige, point...

  10. #10
    Membre confirmé Avatar de 5:35pm
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    201
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2006
    Messages : 201
    Par défaut
    Citation Envoyé par doccpu Voir le message
    Très bonne idée que de faire une dll en bonne et due forme mais à quoi cela sert il si l'on ne corrige pas, par la même occasion, les fuites de mémoires qu'engendre plusieurs appels à createInstance() ?
    oui bon ca va tout le monde sait a quoi ressemble un singleton =)
    ceci dit, cette implementation n'est pas thread safe

  11. #11
    doccpu
    Invité(e)
    Par défaut
    effectivement on a pas mis de sémaphores !

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

Discussions similaires

  1. Pointeur tableau vers DLL VB 2010 Express
    Par guymichela dans le forum VB.NET
    Réponses: 2
    Dernier message: 11/12/2012, 16h50
  2. Exception externe et dll
    Par CédricS dans le forum Delphi
    Réponses: 1
    Dernier message: 21/03/2007, 11h50
  3. Réponses: 13
    Dernier message: 20/06/2005, 14h13
  4. Multithread, pointeur et dll
    Par jakouz dans le forum Langage
    Réponses: 4
    Dernier message: 25/06/2004, 14h37
  5. Dialogue DLL externe
    Par rgarnier dans le forum XMLRAD
    Réponses: 8
    Dernier message: 07/05/2003, 14h28

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