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 :

[DLL] Methodes de classe et dll


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Points : 102
    Points
    102
    Par défaut [DLL] Methodes de classe et dll
    Salut j'ai une question concerant les dll, je voudrait creer une dll avec dedans une classe avec que des methodes statics, une sorte de bibliotheque en fait.

    Ma question est : coment utiliser les methodes de cette classe par la suite.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    LoadLibrary(maDll.dll);
    MaClasse::maFonction();
    ça marche ???

    La dll ne doit rien exporter ?

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Points : 102
    Points
    102
    Par défaut Pardon je suis un boulet....
    Les codes d'export de classe exporte les classes et pas les fonctions classes...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #ifdef PICTUREMODIFYER_EXPORTS
    #define PICTUREMODIFYER_API __declspec(dllexport)
    #else
    #define PICTUREMODIFYER_API __declspec(dllimport)
    #endif
     
    // This class is exported from the PictureModifyer.dll
    class PICTUREMODIFYER_API CPictureModifyer {
    public:
    	static maFonction();
    };
    pardon pour le dérangement, j'apprends a lire....

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Points : 102
    Points
    102
    Par défaut Chargement implicite de dll
    J'ai un leger probleme avec mes dll.
    J'utilise 4 dll qui sont chargées de manière "DELAY" et le probleme est que quand le linker charge la DLL il ne fait apparement pas appel a dllMain. (j'ai tracer le truc en debbug)
    Ma question est donc la suivante :
    1- Ou est specifier l'option d chargement différer ?? (faut il justement poser une option pour ne pas avoir de chargement différé ?)

    2-Avec une chargement différé qui est quand meme plus mieux bien, comment faire pour quand meme passer dasn le dllMAin

    au cas ou voici le code de ma dll

    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
     
    BOOL APIENTRY DllMain( HANDLE , DWORD  ul_reason_for_call,LPVOID)
    {
    	#ifdef DEBUG
    	UNICODE_debugTrace(TEXT("Picture manager : DllMain"));
    	#endif
        switch (ul_reason_for_call)
    	{
    		case DLL_PROCESS_ATTACH:
    			#ifdef DEBUG
    			UNICODE_debugTrace(TEXT("Picture manager : DLL_PROCESS_ATTACH:"));
    			#endif
    			break;
    		case DLL_THREAD_ATTACH:
    			#ifdef DEBUG
    			UNICODE_debugTrace(TEXT("Picture manager : DLL_THREAD_ATTACH"));
    			#endif
    			break;
    		case DLL_THREAD_DETACH:
    			#ifdef DEBUG
    			UNICODE_debugTrace(TEXT("Picture manager : DLL_THREAD_DETACH"));
    			#endif
    			break;
    		case DLL_PROCESS_DETACH:
    			#ifdef DEBUG
    			UNICODE_debugTrace(TEXT("Picture manager : DLL_PROCESS_DETACH"));
    			#endif
    			break;
        }
        return TRUE;
    }
     
    CPictureManager::sayHello()//methode static de ma classe
    {
    	MessageBox(NULL,TEXT("kikou"), TEXT("Error"),MB_ICONERROR);
     
    }
    utilisé comme ça.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CPictureManager::sayHello();
    //et ce sans loadLibrary explicite
    le truc c'est que quad le preogramme quite il passe par dllMain et affiche la trace

  4. #4
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    Le DllMain (s'il est bien spécifié comme entry point de ta dll) est toujours appelé, quelque soit la méthode de chargement. y'a juste un souci dans ton code:
    c'est _DEBUG et pas DEBUG, qui n'est jamais défini, donc...
    Le delay load ça se règle dans les options du projet dans VC++ : Editeur de liens->Entrée->Chargement différé des dll.

  5. #5
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    Supprime ton LoadLibrary. L'utilisation des classes d'une dll se fait de manière implicite (link avec le .lib et ça marche).
    En explicite (avec LoadLibrary/GetProcAddress), c'est très très contraignant et difficile.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Points : 102
    Points
    102
    Par défaut Ba tien ça tombe bien
    Effectivement j'ai vu que ça alli mieux de manière implicite masi j'ai un probleme avec el chargement...
    Je voudraiq que au chargement ma dll lance un thread et je penssais le faire depuis le DllMain sur reception d'un PROCESS_ATTACH.

    Le probleme c'est que avec les chargmenet implicte je vois pas de PROCESS_ATTACH... c'est quand meme tres bizard !
    Je te propose de fusionner avec ce sujet => http://www.developpez.net/forums/viewtopic.php?t=331978
    En fait finalement ça se rejoint !!

    Citation Envoyé par Aurelien.Regat-Barrel
    Le DllMain (s'il est bien spécifié comme entry point de ta dll) est toujours appelé, quelque soit la méthode de chargement. y'a juste un souci dans ton code:
    c'est _DEBUG et pas DEBUG, qui n'est jamais défini, donc...
    Le delay load ça se règle dans les options du projet dans VC++ : Editeur de liens->Entrée->Chargement différé des dll.
    PS: Pour info je travail sur embedVisulaC++ et ce ¤¨%@)£$$ definit DEBUG et pas _DEBUG tu parle si c'est marrant

    Apres avoir essayer de faire un chargement explicit avec loadLibrary mon message apparait bien Le problme est de savoir recuperer un pointeur sur une fonction static de classe dans ma dll...

    Je pourrais faire une fonction d'init (surement ce que je vais faire en fait) mais par simple curiosité tu peux expliquer comment on fait pour recuperer ce genre de truc, merci

  7. #7
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    T'as vraiment pas choisi la méthode facile.
    Avec une liaison implicite, ça devrait marcher. Pose un MessageBox dans le DllMain pour être sûr.
    Après si tu veux importer une classe dynamiquement, c'est du bricolage. Faut créer une classe de base abstraite (que des fonctions membres virtuelles pures), et gérer un mécanisme de création dans ta dll qui renvoie un pointeur sur cette classe (fait office de new en fait). La dll en interne dérive et implémente la classe de base abstraite (factory).
    Bref tu recrée à la main le principe de COM...
    Et ça ne marche pas pour les fonctions statiques. Faut exporter ces dernières comme des fonctions libres classiques, en tant que fonction C de préférence, sinon tu vas devoir te cogner le name mangling ce qui ne va pas arranger les choses (des noms du genre "?bitBlt@@YAXPAVQPaintDevice@@ABVQPoint@@PBV1@ABVQRect@@W4RasterOp@Qt@@_N@Z").

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Points : 102
    Points
    102
    Par défaut je suis convaincu n'en jetez plus !
    Ok ça me conforte dans mon idée je vais me debrouiller autrement !....
    A y est j'ai fait avec de l'appel implicite (c'est vrai c'est bien) Alors voilà je test une classe de base toute de base qui dit bonjour et c'est tout, la methode est static pas de problem ça marche...
    Ensuite je retrousse me tites maches et je passe à mon vrai truc.
    Un singleton manager de fichier. Je li bien comme y faut la faq le forum et hop je choisi le singleton le plus simple que voici

    .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
    class PICTUREMANAGER_API CPictureManager  
    {
    private:
    	int    m_i; 
        static CPictureManager * m_p; 
     
    	CPictureManager();
    	~CPictureManager();
    protected:
    public:
    	void    SetValue( int iValue );
        int     GetValue();
     
    	static CPictureManager * GetInstance( void );
    	static Kill();
     
    	static sayHello();
    };
    .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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    CPictureManager::~CPictureManager()
    {
    }
     
    CPictureManager::CPictureManager()
    {
    }
     
    CPictureManager::sayHello()
    {
    	MessageBox(NULL,TEXT("Hello you"), TEXT("Info."),MB_ICONINFORMATION);
    }
     
    CPictureManager* CPictureManager::GetInstance() 
    { 
        if( m_p == 0 ) 
        { 
    		#ifdef DEBUG
    		UNICODE_debugTrace(TEXT("Creation of PictureManager"));
    		#endif
    		m_p = new CPictureManager();
        } 
        else 
        { 
    		#ifdef DEBUG
            UNICODE_debugTrace(TEXT("PictureManager allready exist here is the handle"));
    		#endif
        } 
     
        return m_p; 
    } 
     
    CPictureManager::Kill() 
    { 
        if( m_p != 0 ) 
        { 
            delete m_p; 
            m_p = 0; 
     
    		#ifdef DEBUG
    		UNICODE_debugTrace(TEXT("PictureManager has been killed"));
    		#endif
        } 
    } 
     
    void CPictureManager::SetValue( int i )
    {
    	this->m_i = i;
    }
     
    int CPictureManager::GetValue()
    {
    	return this->m_i;
    }
    Normalemnt ce truc fonctionne, le truc c'est qeu c'est que le projet veut mem pas compiler !
    Creating library .././bin/debug/emulator/PictureManager.lib and object .././bin/debug/emulator/PictureManager.exp
    PictureManager.obj : error LNK2001: unresolved external symbol "private: static class CPictureManager * CPictureManager::m_p" (?m_p@CPictureManager@@0PAV1@A)
    .././bin/debug/emulator/PictureManager.dll : fatal error LNK1120: 1 unresolved externals
    ALors vienne deux question, bien sur pourquoi que ça marche pô et deuxiemement tous les singleton que j'ai vu sont dans le meme espace memoire que le prog, c'est super cool pour fair l'init du pointeur sur l'instance mais avec une dll comment on fait ça ???

  9. #9
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    1/ réponse dans la FAQ:
    http://c.developpez.com/faq/cpp/?pag...SS_init_static
    2/ pas compris

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Points : 102
    Points
    102
    Par défaut 1000 excuses
    En fait ya pas de deux il suffisait de faire l'init dans le cpp comme tu m'as dit, je penssais pas embeter le linker à ce point la , m'enfin c'est noté pour la prochaine fois
    Pour les suivants je laisse le code fonctionnel
    .h du singleton

    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
     
    #ifdef PICTUREMANAGER_EXPORTS
    #define PICTUREMANAGER_API __declspec(dllexport)
    #else
    #define PICTUREMANAGER_API __declspec(dllimport)
    #endif
     
    class PICTUREMANAGER_API CPictureManager  
    {
    private:
    	int    m_i; 
        static CPictureManager * m_p; 
     
    	CPictureManager();
    	~CPictureManager();
    protected:
    public:
    	void    setVal( int iValue );
        int     getVal();
     
    	static CPictureManager * GetInstance( void );
    	static Kill();
     
    	static sayHello();
    };
    et .cpp du singleton
    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
     
     
    CPictureManager* CPictureManager::m_p = 0;//tres important sinon a link pô
     
    CPictureManager::~CPictureManager()
    {
    }
     
    CPictureManager::CPictureManager()
    {
    }
     
    CPictureManager::sayHello()
    {
    	MessageBox(NULL,TEXT("Hello you"), TEXT("Info."),MB_ICONINFORMATION);
    }
     
    CPictureManager* CPictureManager::GetInstance() 
    { 
        if( CPictureManager::m_p == 0 ) 
        { 
    		#ifdef DEBUG
    		UNICODE_debugTrace(TEXT("Creation of PictureManager"));
    		#endif
    		CPictureManager::m_p = new CPictureManager();
        } 
        else 
        { 
    		#ifdef DEBUG
            UNICODE_debugTrace(TEXT("PictureManager allready exist here is the handle"));
    		#endif
        } 
        return CPictureManager::m_p; 
    } 
     
    CPictureManager::Kill() 
    { 
        if( CPictureManager::m_p != 0 ) 
        { 
            delete CPictureManager::m_p; 
            CPictureManager::m_p = 0; 
     
    		#ifdef DEBUG
    		UNICODE_debugTrace(TEXT("PictureManager has been killed"));
    		#endif
        } 
    } 
     
    void CPictureManager::setVal( int i )
    {
    	this->m_i = i;
    }
     
    int CPictureManager::getVal()
    {
    	return this->m_i;
    }
    et voilà en plus ça marche merci Aurelien.Regat-Barrel

  11. #11
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    Faut pas oublier le Kill...
    Plus simple, sans Kill() et sans m_p:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    CPictureManager* CPictureManager::GetInstance() 
    { 
        static CPictureManager instance;
        return &instance;
    }

  12. #12
    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 : 40
    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
    Pour pinailler, si l'on utilise une instance statique de cette manière pas la peine de renvoyer un pointeur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CPictureManager& CPictureManager::GetInstance()
    {
        static CPictureManager instance;
        return instance;
    }
    Mais si tu as des dépendances entre singletons ou autre il vaut mieux éviter cette méthode allegée et te rabattre sur l'autre. Car là tu ne pourras pas contrôler la destruction du singleton.

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

Discussions similaires

  1. Appel d'une methode de classe par message inopérant dans une dll
    Par Jacques Deyrieux dans le forum API, COM et SDKs
    Réponses: 3
    Dernier message: 10/08/2010, 08h10
  2. Réponses: 4
    Dernier message: 10/04/2006, 16h12
  3. Classes et Dll.
    Par jamais34 dans le forum MFC
    Réponses: 3
    Dernier message: 03/03/2006, 19h43
  4. [Debutant(e)]Dossiers .java, .class et .dll
    Par jeanmm dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 12/01/2006, 14h43
  5. Réponses: 4
    Dernier message: 08/10/2005, 09h31

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