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 :

Problème : créer une classe dans une dll et l'exporter dans une application.


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15
    Points : 10
    Points
    10
    Par défaut Problème : créer une classe dans une dll et l'exporter dans une application.
    Bonjour,

    Je voudrais mettre une classe dans une dll puis utiliser cette classe dans une application qui utiliserait la dll .

    Seulement je n'arrive pas à instancier ma calss qui estdans la dll une fois la dll chargée.

    j'ai repirs le code de la présentation suivante :

    http://lfe.developpez.com/DLL/#L6

    donc la class foo est exactement comme dans lexemple dans un fichier foo.cpp et foo .h
    mais ca cloche quelque part.

    voici le code de ma dll :

    #include "foo.h"

    IMPEXP foo ;

    #pragma argsused
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
    return 1;
    }
    Voila si quelqu'un a la réponse merci.

    Sinonle source de l'exemple aurait été bien utile.

  2. #2
    Membre expert
    Avatar de hiko-seijuro
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 011
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 011
    Points : 3 065
    Points
    3 065
    Par défaut
    elle est ou ta classe ?
    Hiko-seijuro

    n'cha - hoyoyo gang

    espace perso : http://hiko-seijuro.developpez.com
    dernier tuto : Introduction à l'éditeur de texte Emacs sous linux
    consulter les faqs : http://www.developpez.com/faq
    PAS DE QUESTIONS TECHNIQUES PAR MP OU MAIL

  3. #3
    Membre à l'essai
    Inscrit en
    Avril 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 24
    Points : 19
    Points
    19
    Par défaut
    tou dépend si ta DLL est chargé implicitement ou explicitement !
    en bref si tu a utilisé un dllexport dll import (implicite) ou un loadlibrary()(explicite)

    selon les deux cas ce nest pas le meme probleme !

    en implicite tu pourra utiliser la classe de ta dll comme si elle etait dans ton programme tandi qu'en explicite c plus compliqué !

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15
    Points : 10
    Points
    10
    Par défaut désolé c'est parcequ'elle étaitdans l'exemple cité, voilà la classe
    Voila le code de la classe :

    .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
     
    #ifdef __DLL__
    #define IMPEXP __declspec(dllexport)
    #else
    #define IMPEXP __declspec(dllimport)
    #endif
     
    //---------------------------------------------------------------------------
    IMPEXP class foo {
        public:
            int N1, N2, Result;
            void __stdcall AddN();
            int __stdcall GetResult();
            foo();
    };
    .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
     
    #include "foo.h"
     
    foo::foo()
    {
        N1 =0;
        N2 =0;
        Result=0;
    }
     
    void __stdcall foo::AddN()
    {
        Result = N1 + N2;
    }
     
    int __stdcall foo::GetResult()
    {
        return Result;
    }

    et le code d'importation :

    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
     
    #include <vcl.h>
    #pragma hdrstop
     
    #include "Unit2.h"
     
    extern "C" __declspec(dllimport) foo ;
     
     
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TFormT *FormT;
    //---------------------------------------------------------------------------
    __fastcall TFormT::TFormT(TComponent* Owner)
            : TForm(Owner)
    {
      foo * test ;
    }

  5. #5
    Membre à l'essai
    Inscrit en
    Avril 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 24
    Points : 19
    Points
    19
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #ifdef __DLL__
    #define IMPEXP __declspec(dllexport)
    #else
    #define IMPEXP __declspec(dllimport)
    #endif

    dans le .h de ta DLL il faut que tu fasse un #define __DLL__ pour activer le mode export

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15
    Points : 10
    Points
    10
    Par défaut Ya pas de .h dans la dll
    j'ai pas de .h pour la dll ya juste un .cpp

    ca serait pas plutotdans le .h de la classe ?

    et pour l'importation dans l'appli c'est bon ou il faut faire autre chose ?

    merci.

  7. #7
    Membre à l'essai
    Inscrit en
    Avril 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 24
    Points : 19
    Points
    19
    Par défaut
    oui c ce que je voulai dire désolé !

    DLL:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #ifdef __DLL__
    #define IMPEXP __declspec(dllexport)
    #else
    #define IMPEXP __declspec(dllimport)
    #endif
     
    #define __DLL__
     
    class IMPEXP NomDeClass
    {
          // déclarations normales sans __stdcall
    };
    prog:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #include "classeDLL.h"
     
    NomDeClass xxx;   // instance de la classe
    normalement comme cela ca marche il faut penser a ajouter ta DLL dans les dependence de ton executable car c'est du chargement implicite

  8. #8
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #ifdef __DLL__
    #define IMPEXP __declspec(dllexport)
    #else
    #define IMPEXP __declspec(dllimport)
    #endif
     
    #define __DLL__
     
    class IMPEXP NomDeClass
    {
    // déclarations normales sans __stdcall
    };
    Le #define __DLL__ ne sert à rien ici (il est défini après qu'il soit testé). Il faut le définir non pas dans le code, mais dans les options du préprocesseur. Ca évitera aussi qu'il soit défini dans les programmes clients.

  9. #9
    Membre à l'essai
    Inscrit en
    Avril 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 24
    Points : 19
    Points
    19
    Par défaut
    oui il est mal pmacé dsl

    en plus le #define __DLL__ est a placer dans le programme principale avant l'inclusion du .h de la classe de la dll et pas dan la dll
    encore dsl

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15
    Points : 10
    Points
    10
    Par défaut Hmmmm...
    Dites moi si je me trompe mais si on est obligé d'inclure le .h de la classe qui est contenue dans la dll dans le soft qui utilisera la dll, ou est l'interet d'avoir une dll qui contient une classe plutot qu'une classe toute simple ?

    En fait mon but est d'avoir une dll qui contient une ou plusieurs classes que je puisse réutilisé dans la conception de mes application pour ne pas avoir à les redelcarées et importer les .h à chaque fois.

    Ce qui me permettrait pour une mise à jour de ne changer que la dll sans recompiler toutes les aplpications.

    Mais peut être je suis partit sur une mauvaise piste ?

  11. #11
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Mais peut être je suis partit sur une mauvaise piste ?
    Oui. Pour utiliser une classe, qu'elle vienne d'une DLL ou d'ailleurs, il faut sa définition, donc son .h.

  12. #12
    Membre à l'essai
    Inscrit en
    Avril 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 24
    Points : 19
    Points
    19
    Par défaut
    pour procéder comme tu le di, ne pas recompiler ton prog a chaque changemen de la DLL, le mieu serai de la charger explicitement par un LoadLibrary("xxx.dll")
    ainsi le prog et celle ci serais réellement indépendant !

  13. #13
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Citation Envoyé par GEIIMAN
    pour procéder comme tu le di, ne pas recompiler ton prog a chaque changemen de la DLL, le mieu serai de la charger explicitement par un LoadLibrary("xxx.dll")
    ainsi le prog et celle ci serais réellement indépendant !
    Il faudra quand même le prototype des fonctions que l'on va récupérer dans la DLL. Le seul moyen d'utiliser une DLL sans la moindre dépendance c'est d'utiliser une classe de base et de jouer avec les fonctions virtuelles. C'est le principe utilisé en général par les plug-in.

  14. #14
    En attente de confirmation mail
    Inscrit en
    Avril 2004
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 83
    Points : 54
    Points
    54
    Par défaut
    Bonjour, je me permet de relancer la discussion car j'ai le même soucis d' exportation d'une classe dans une DLL.
    Voici mon code :
    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
    //DLL3.cpp (contenu de la DLL)
    #include "DLL3.h"
     
    extern "C" __declspec(dllexport) int maclasse::addition(int a,int b)
    {
    	return a+b;
    }
     
    extern "C" __declspec(dllexport) int maclasse::soustraction(int a,int b)
    {
    	return a-b;
    }
    extern "C" __declspec(dllexport) int maclasse::multiplication(int a,int b)
    {
    	return a*b;
    }
    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
    //DLL3.h
    #ifdef __DLL__
    #define IMPEXP __declspec(dllexport)
    #else
    #define IMPEXP __declspec(dllimport)
    #endif
     
    #define __DLL__
     
     
    class IMPEXP maclasse{
    	public :
     	  int addition(int a,int b);
    	  int soustraction(int a,int b);
    	  int multiplication(int a,int b);
     
    };
    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
    //dll3exec.cpp (exploitation de la DLL)
    #include <iostream>
     
    using namespace std;
     
    extern "C" __declspec(dllimport) int maclasse::addition(int,int) ;
    extern "C" __declspec(dllimport) int maclasse::soustraction(int,int) ;
    extern "C" __declspec(dllimport) int maclasse::multiplication(int,int) ;
     
     
    int main()
    {
    	int a =100;
    	int b=25;
     
    	int total = maclasse::addition(a,b) ;
    	cout<<a<<"+"<<b<<"="<<total<<endl;
     
    	total = maclasse::soustraction(a,b) ;
    	cout<<a<<"-"<<b<<"="<<total<<endl;
     
    	total = maclasse::multiplication(a,b) ;
    	cout<<a<<"*"<<b<<"="<<total;
    	cin.get();
    	return 0;
    }
    Mon soucis c'est que la compil de la dll me met 3 warning du type :
    >warning C4273: 'maclasse::soustraction' : liaison DLL incohérente
    et ceci pour addition, soustraction et multiplication.

    Je persiste et quand je lance mon exec avec exploitation de la dll, j'obtiens l'erreur suivante :
    >error C2653: 'maclasse' : n'est pas un nom de classe ni d'espace de noms
    et ceci autant de fois que j'utilise "maclasse::..."

    J'espère que j'ai bien expliqué mon problème.
    Merci de m'aider

  15. #15
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #ifdef __DLL__
    #define IMPEXP __declspec(dllexport)
    #else
    #define IMPEXP __declspec(dllimport)
    #endif
     
    #define __DLL__
    Tu as mal lu la fin de la discussion, notamment ceci :
    http://www.developpez.net/forums/sho...21&postcount=8

    Ensuite il ne faut pas que tu utilises extern "C" __declspec(dllexport) dans l'implémentation des fonctions, puisque toute ta classe est déjà exportée via la directive IMPEXP.

    Enfin, il faut évidemment que tu inclues l'en-tête qui définit ta classe pour l'utiliser dans le programme client.

  16. #16
    En attente de confirmation mail
    Inscrit en
    Avril 2004
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 83
    Points : 54
    Points
    54
    Par défaut
    Merci !!!

    Alors, j'ai enlevé la ligne #define __DLL__ de DLL3.h.
    J'ai également enlevé les "C" __declspec(dllexport) de DLL3.cpp.

    Je compile , ça va bien même si j'ai les mêmes warning qu'avant, cad :
    > 'maclasse::addition' : 'extern' spécificateur de classe de stockage non conforme sur définition de membre
    > warning C4273: 'maclasse::addition' : liaison DLL incohérente
    et ceci 3 fois pour mon DLL3.cpp.

    A partir de là, je copie DLL3.h, DLL3.lib et DLL3.dll dans le dossier de mon projet qui exploite cette DLL.

    Dans DLL3exec.cpp, voici maintenant les nouvelles lignes précédants mon main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #include <iostream>
    #include "DLL3.h"
    using namespace std;
    int main...
    Là, j'ai 3 errors du style :
    > error C2352: 'maclasse::addition' : appel non conforme d'une fonction membre non static

    Voila donc ce que j'obtiens après ces modifs. J'ai essayé de debugger pendant 1/2 heures mais

    J'espere que quelqu'un saura m'éclairer de la même façon !

  17. #17
    En attente de confirmation mail
    Inscrit en
    Avril 2004
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 83
    Points : 54
    Points
    54
    Par défaut
    J'aurai du chercher un peu plus .
    J'avais pas mis mes déclarations en static...

    Et ca marche

    Par contre, j'ai toujours mes warnings de DLL3.cpp...

  18. #18
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    On peut voir le nouveau code de DLL3.h ?
    Tu as bien défini __DLL__ dans les options du préprocesseur ?

  19. #19
    En attente de confirmation mail
    Inscrit en
    Avril 2004
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 83
    Points : 54
    Points
    54
    Par défaut
    Citation Envoyé par Laurent Gomila
    Tu as bien défini __DLL__ dans les options du préprocesseur ?
    En effet, j'avais oublié

    En ayant réctifié cela , je suis passé de 6 à 3 warnings , c'est mieux!

    Les warning restants sont les suivants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    c:\...\DLL3.cpp(5) : warning C4630: 'maclasse::addition' : 'extern' spécificateur de classe de stockage non conforme sur définition de membre
    c:\...\DLL3.cpp(10) : warning C4630: 'maclasse::soustraction' : 'extern' spécificateur de classe de stockage non conforme sur définition de membre
    c:\...\DLL3.cpp(14) : warning C4630: 'maclasse::multiplication' : 'extern' spécificateur de classe de stockage non conforme sur définition de membre
    Voici mon DLL3.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #ifdef __DLL__
    	#define IMPEXP __declspec(dllexport)
    #else
    	#define IMPEXP __declspec(dllimport)
    #endif
     
    class IMPEXP maclasse{
     
    	public :
     		static	int addition		(int a,int b);
    		static  int soustraction	(int a,int b);
    		static  int multiplication	(int a,int b);
    };
    et mon DLL3.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
    #include "DLL3.h"
     
    extern int maclasse::addition(int a,int b)
    {
    	return a+b;
    }
    extern int maclasse::soustraction(int a,int b)
    {
    	return a-b;
    }
    extern  int maclasse::multiplication(int a,int b)
    {
    	return a*b;
    }
    "'extern' spécificateur de classe de stockage non conforme sur définition de membre" hum...

  20. #20
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    En effet, extern n'a rien à faire devant une définition de fonction membre.

Discussions similaires

  1. Réponses: 2
    Dernier message: 23/05/2013, 02h22
  2. Export d'une classe MFC d'un programme vers DLL
    Par yann458 dans le forum MFC
    Réponses: 1
    Dernier message: 16/05/2013, 10h00
  3. Réponses: 3
    Dernier message: 29/06/2012, 01h09
  4. Dans quel script est la definition d'une classe, d'une fonction,
    Par debutant100 dans le forum Général Python
    Réponses: 6
    Dernier message: 05/04/2011, 19h19
  5. Réponses: 5
    Dernier message: 27/11/2009, 09h21

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