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 :

Accéder à une classe dérivée d'une dll par polymophisme


Sujet :

C++

  1. #1
    Membre averti Avatar de Flo.
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2002
    Messages : 379
    Points : 404
    Points
    404
    Par défaut Accéder à une classe dérivée d'une dll par polymophisme
    Bonjour,

    Depuis une application, je cherche à accéder à une classe A dérivant d'une classe B abstraite sachant que la classe A se trouve dans une dll et que l'application connaît la classe B uniquement.

    J'aimerais que cet accès à la classe A se fasse donc via le mécanisme de polymorphisme c'est-à dire comme un objet de classe B.

    Voilà grosso-modo le code

    B.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class B
    {
    public: virtual void foo() = 0;
    };
    A.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include "B.h"
     
    class __declspec(dllexport) A : public B
    {
    public: void foo();
    };
    A.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #include "A.h"
     
    void A::foo(){}
    DLLEntry.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include "A.h"
     
    BOOL APIENTRY DllMain(HINSTANCE, unsigned long reason_for_call, void*)
    { 
           return TRUE;
    }
     
    extern "C" __declspec(dllexport) B * CreateB()
    {	
    	return new A;
    }
    Dans l'exe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include "B.h"
     
    // chargement dynamique de A.dll et récupération d'un pointeur sur CreateB
     
    B * unA = CreateB(); // pas de soucis
    unA->foo(); // crash
    J'arrive à compiler dll et application. Le chargement de la dll se fait correctement ainsi que l'appel de la fonction CreateB. Cependant dés que j'essaie d'accéder à une fonction de l'objet créé, j'ai un crash. On dirait que j'accède à la fonction foo de la classe abstraite B et non de la classe A.

    J'ai trouvé pleins de choses sur le net mais sans succès.

    Je me mélange aussi les pédales dans toutes ces histoires de declspec que je ne maîtrise pas.

    Flo.

  2. #2
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Inutile d'exporter la classe A.

    Sinon, à part le fait que le compilateur, la version du compilateur et les options de compilation doivent être les mêmes (modulo les settings DEBUG / RELEASE sur certains compilateurs), je ne vois pas pourquoi ça ne marcherais pas.

    Il faut aussi faire en sorte que l'objet créé dans la DLL soit aussi détruit dans la DLL - car la DLL peut utiliser un mécanisme d'allocation différent de celui du programme (notamment en cas de différence DEBUG / RELEASE).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  3. #3
    Membre averti Avatar de Flo.
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2002
    Messages : 379
    Points : 404
    Points
    404
    Par défaut
    Dll et exe sont compilés en même temps via mingw avec les mêmes options de compilation. Voilà mon makefile :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    OBJECTS_A_DLL = A.o DllEntry.o
    OBJECTS_MAIN = main.o
     
    all: A.dll executable.exe 
     
    executable.exe: $(OBJECTS_MAIN)
    	g++ -g -o $@ $^ -Wl,--enable-auto-import
     
    A.dll: $(OBJECTS_A_DLL)
    	g++ -g -shared -o $@ $^ -Wl,--enable-auto-import  -Wl,--out-implib=libA.a
     
    %.o: %.cpp
    	g++ -g -c -o $@ $^
    Que je mette __declspec(dllexport) ou pas n'y change rien.

    Je joints le projet compilable via un "make all" si ça vous dit d'y jeter un oeil.

    Merci

    Flo.
    Fichiers attachés Fichiers attachés

  4. #4
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par Flo. Voir le message
    Je joints le projet compilable via un "make all" si ça vous dit d'y jeter un oeil.
    Je voudrais bien, mais je suis sous Linux
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  5. #5
    Membre averti Avatar de Flo.
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2002
    Messages : 379
    Points : 404
    Points
    404
    Par défaut
    Pas grave ami linuxien ...

    Merci pour ton aide cross-platform

    Flo.

  6. #6
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    J'ai trouvé ton problème, et j'ai utilisé Visual C++ en debugging pour comprendre.

    Deux problèmes:
    - A::foo() doit être virtuelle. Elle ne l'est pas.
    - FreeLibrary(DLLHandle); ne doit pas être appelé tant que tu as besoin de la DLL, car ça la décharge... Si tu le commentes, ça fonctionne.

    En bonus, le CMakeLists.txt que j'ai utilisé (plus pratique que ces diables de makefiles) :

    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
    cmake_minimum_required (VERSION 2.6)
     
    project(TestForDVP)
    set(CMAKE_VERBOSE_MAKEFILE OFF)
     
    ### Commons includes ###
    include_directories(
        ${TestForDVP_SOURCE_DIR}/
        ${TestForDVP_BINARY_DIR}/
    	)
     
    ### Linking ###
    add_library(A SHARED A.cpp DLLEntry.cpp)
    add_executable(${PROJECT_NAME} Main.cpp)
    target_link_libraries(${PROJECT_NAME} A)
    Find me on github

  7. #7
    Membre averti Avatar de Flo.
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2002
    Messages : 379
    Points : 404
    Points
    404
    Par défaut
    Oui maintenant que t'en parles ça tombe sous le sens de ne libérer la dll qu'après son utilisation.

    Quant à virtuel c'était un oubli de ma part dans mon projet exemple.

    Tout marche bien maintenant.

    Merci beaucoup

    Flo.

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

Discussions similaires

  1. Redéfinir une méthode static dans une classe dérivée
    Par michelp3 dans le forum Général Java
    Réponses: 5
    Dernier message: 06/05/2015, 22h28
  2. accéder à classe dérivée via une classe de base
    Par wirenth dans le forum Langage
    Réponses: 6
    Dernier message: 28/09/2011, 11h23
  3. Réponses: 7
    Dernier message: 05/04/2011, 17h19
  4. construire automatiquement les classes dérivée a une class mere
    Par elekis dans le forum Général Python
    Réponses: 17
    Dernier message: 09/06/2009, 20h53
  5. Réponses: 8
    Dernier message: 20/07/2007, 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