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

Visual C++ Discussion :

[DLL MFC] Plantage et débugage d'une DLL


Sujet :

Visual C++

  1. #1
    Membre actif

    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2003
    Messages
    286
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 286
    Points : 255
    Points
    255
    Par défaut [DLL MFC] Plantage et débugage d'une DLL
    Salut,

    Je développe sous VS2008 à la création d'une DLL.
    J'ai fais une dll basique que je n'arrive malheureusement pas à faire marcher -> explosion dans la dll avec des pointeurs incorrects ...

    J'ai mis en piece jointe la solution VC++ 2008 qui contient 2 projets : la dll et le programme d'exemple.
    Le débugage de l'ensemble fait exploser l'application dès que l'on arrive dans la fonction exportée.

    Voici le code de la dll mfc (dll partagée) :

    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
    // Test DLL.h*: fichier d'en-tête principal pour la DLL Test DLL
    //
     
    #pragma once
     
    #ifndef __AFXWIN_H__
    	#error "incluez 'stdafx.h' avant d'inclure ce fichier pour PCH"
    #endif
     
    #include "resource.h"		// symboles principaux
     
     
    // CTestDLLApp
    // Consultez Test DLL.cpp pour l'implémentation de cette classe
    //
     
    class CTestDLLApp : public CWinApp
    {
    public:
    	CTestDLLApp();
     
    	int TestFunc();
     
    private:
    	CString m_chaine1;
    	CString m_chaine2;
     
    // Substitutions
    public:
    	virtual BOOL InitInstance();
     
    	DECLARE_MESSAGE_MAP()
    };


    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
    // Test DLL.cpp*: définit les fonctions d'initialisation pour la DLL.
    //
     
    #include "stdafx.h"
    #include "Test DLL.h"
     
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
     
     
    // CTestDLLApp
     
    BEGIN_MESSAGE_MAP(CTestDLLApp, CWinApp)
    END_MESSAGE_MAP()
     
     
    // construction CTestDLLApp
     
    CTestDLLApp::CTestDLLApp()
    {
    	// TODO*: ajoutez ici du code de construction,
    	// Placez toutes les initialisations significatives dans InitInstance
    }
     
     
    // Seul et unique objet CTestDLLApp
     
    CTestDLLApp theApp;
     
     
    // initialisation de CTestDLLApp
     
    BOOL CTestDLLApp::InitInstance()
    {
    	CWinApp::InitInstance();
     
    	m_chaine1 = "Toto";
    	m_chaine2 = CString("Robert");
     
    	return TRUE;
    }
     
     
     
    int CTestDLLApp::TestFunc()
    {
    	AFX_MANAGE_STATE(AfxGetStaticModuleState());
     
    	m_chaine1 = "pouet";
    	m_chaine2 = "blabla";
     
    	return 0;
    }

    Le fichier DEF :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ; Test DLL.def : déclare les paramètres de module pour la DLL.
     
    LIBRARY      "Test DLL"
     
    EXPORTS
        ; Les exportations explicites peuvent être placées ici
    	TestFunc	@1
    Y'a t'il quelque chose d'incorrect dans ma dll ?



    Voici en gros le code de l'appli test (dialog based) :


    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
    typedef int (* TESTFUNC)();
     
     
    // boîte de dialogue CApplitestDlg
    class CApplitestDlg : public CDialog
    {
    // Construction
    public:
    	CApplitestDlg(CWnd* pParent = NULL);	// constructeur standard
     
    	TESTFUNC TestFunc; //Entête de la fonction
     
    	int InitDll(); //Initialisation de La dll
    	FARPROC GetProc(char *Fonction); //Récupération et affectation des méthodes de la dll
     
     
    private:
    	HMODULE ModuleLib; //Module pour le chargement de la dll BT
     
    ...
     
    };

    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
    BOOL CApplitestDlg::OnInitDialog()
    {
    ...
     
    	// TODO : ajoutez ici une initialisation supplémentaire
    	InitDll();
     
    	return TRUE;  // retourne TRUE, sauf si vous avez défini le focus sur un contrôle
    }
     
    void CApplitestDlg::OnDestroy()
    {
    	CDialog::OnDestroy();
    	FreeLibrary(ModuleLib);
    }
     
     
    //Méthode de chargement de la dll BT
    int CApplitestDlg::InitDll() 
    {
    	ModuleLib = LoadLibrary( CString("Test DLL.dll") );
    	if(ModuleLib == NULL)
    	{
    		TCHAR chaine[100];
    		int Erreur = GetLastError();
    		wsprintf(chaine, _T("Problème de chargement de la dll !"), Erreur);
    		AfxMessageBox(chaine);
    		return -1;
    	}
    	TestFunc		= (TESTFUNC) GetProc("TestFunc");
     
    	return 0;
    }
     
    //Méthode d'affectation des fonctions de la dll BT
    FARPROC CApplitestDlg::GetProc(char *Fonction)
    {
    	FARPROC fonc = GetProcAddress(ModuleLib, Fonction);
    	if(fonc == NULL)
    		{
    		  char ErreurMessage[200] = "Fonction non trouvée !";
    		  strcat(ErreurMessage, Fonction) ;
    		  AfxMessageBox(CString(ErreurMessage));
    		}
    	return fonc;
    }
     
     
     
    void CApplitestDlg::OnBnClickedButton1()
    {
    	int err = 0;
     
    	err = TestFunc();
    }
    Je ne comprends vraiment pas ou se trouve le problème ! C'est on ne peut plus basique ....

    J'en arrive à me demander si le fait de débugger une dll et son programme d'exemple ne fait pas exploser l'ensemble !

    Merci !
    Fichiers attachés Fichiers attachés

  2. #2
    Membre actif

    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2003
    Messages
    286
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 286
    Points : 255
    Points
    255
    Par défaut


    Je ne comprends pas.

    Le résultat est exactement le même en compilant sous VC6.0

    Je fais vraiment une erreur mais laquelle ?

    Est-il possible d'utiliser un CString définie dans la classe dans une fonction exportée ?

    merci

  3. #3
    Membre éprouvé
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Points : 1 067
    Points
    1 067
    Par défaut
    Je ne suis pas très doué dans l'export des classes MFC, mais d'après ce que j'ai pu voir, je pense que ton problème vient du fait que tu exportes juste une fonction de la classe. Donc quand ton programme de test appelle cette fonction, aucune instance de la classe de la DLL n'existe.
    Il y a donc une tentative d'accès, via la fonction exportée, aux membres de la classe, classe qui n'existe pas et dont le membres, par définition, n'existent pas non plus!

    Je pense que tu dois exporter la classe complète et l'instancier avant d'y faire appel.

    A faire confirmer par quelqu'un qui s'y connaît plus que moi

  4. #4
    Membre actif

    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2003
    Messages
    286
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 286
    Points : 255
    Points
    255
    Par défaut
    Et bien je passe bien dans le InitInstance de la dll quand j'utilise LoadLibrary depuis le programme appelant !
    Donc pour moi il n'y a pas de raisons qu'il n'y ait pas d'instance de classe !

    Et je ne comprends pas pourquoi il faudrait que j'exporte toute ma classe si je ne souhaite pouvoir accéder qu'à une fonction de cette classe (qui apparemment est instanciée ...)

  5. #5
    Membre éprouvé
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Points : 1 067
    Points
    1 067
    Par défaut
    Encore une fois, je ne suis pas une star de l'export, ce que je dis est donc à prendre avec beaucoup de précaution.
    Mais toujours est-il que quand j'arrive en debug (à partir des sources que tu as fournies) dans la fonction de la classe de la DLL, le this est undefined. Les accès aux m_Chaine1 et m_Chaine2, eux aussi indéfinis, provoquent donc les erreurs dont tu parlais dans ton premier post.
    Peut-être manque-t-il quelque chose dans le InitInstance() de ta DLL?

    Je te conseille de parcourir la section de la FAQ Visual C++ qui correspond aux DLL, peut-être que tu y trouveras des informations qui te parleront plus qu'à moi .

  6. #6
    Membre actif

    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2003
    Messages
    286
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 286
    Points : 255
    Points
    255
    Par défaut
    Merci pour tes réponses, déjà.

    On est d'accord, quand on debug, ca va pas du tout

    Du côté de la FAQ, je n'ai rien vu ...
    J'ai pas mal recherché mais j'ai pas trouvé d'infos ...

    Bon, j'ai testé plusieurs trucs mais je comprends de moins en moins ....

    J'ai essayé de mettre mes variables de classe en static, ca a marché dans un premier temps mais forcément ca finit par exploser quand je complète mon programme ...

    J'ai essayé ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int LancePaiement(char* _portTPE, char* _montant)
    {
    	AFX_MANAGE_STATE(AfxGetStaticModuleState());
    	return theApp.TPELancePaiement(_portTPE, _montant);
    }
     
    int CDLLTPEApp::TPELancePaiement(char* _portTPE, char* _montant)
    {
    	portTPE = CharEtoileToCString(&_portTPE[0]);
    	montant = CharEtoileToCString(&_montant[0]);
    	...
    }
    LancePaiement est la fonction exportée.

    Quand je lance l'application, ca fonctionne apparemment correctement.
    Quand je débuggue la dll, ca fonctionne, mais mes pointeurs, mes données .. en résumé tout vaut n'importe quoi !!

    Donc je n'arrive pas à savoir si c'est une bonne méthode, si c'est de la chance, si le débuggeur est buggé (^^)

    Help !

  7. #7
    Membre actif

    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2003
    Messages
    286
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 286
    Points : 255
    Points
    255
    Par défaut
    Je désespère de trouver une solution

    Les dll existent depuis + de 10 ans, ca doit pas être si compliqué comme problème ?!

  8. #8
    Membre éprouvé
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Points : 1 067
    Points
    1 067
    Par défaut
    Citation Envoyé par basinfo
    Quand je lance l'application, ca fonctionne apparemment correctement.
    Les résultats attendus sont présents ou c'est juste que ton programme ne plante pas?
    Citation Envoyé par basinfo
    Quand je débuggue la dll, ca fonctionne, mais mes pointeurs, mes données .. en résumé tout vaut n'importe quoi !!
    Je ne suis pas assez utilisateur de fonctions exportées pour trouver ton problème et le corriger. Tout ce que je peux faire, c'est de t'inciter (encore) à consulter la FAQ, les tutoriaux et cours de ce site ou d'un autre.

    Bon courage

  9. #9
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    salut,
    je viens de lire le post,
    c'est normal que ça plante , tu ne peut exporter une méthode d'une classe.
    tu dois exporter une fonction en C, de ce point de vue la faq donne tout les éléments et avec un exemple.
    de plus je ne vois pas l'intérêt ici de lire la dll avec LoadLibrary ...
    http://cpp.developpez.com/faq/vc/?page=DLL#MakeDynDll

  10. #10
    Membre actif

    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2003
    Messages
    286
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 286
    Points : 255
    Points
    255
    Par défaut
    Merci pour vos réponses

    > spoutspout :

    Les résultats sont bons sur 2 PCs différents, mais si je débugue VS m'affiche vraiment n'importe quoi dans les variables !

    > farscape :

    Dans mon 2ème exemple j'exporte une fonction qui ne fait pas partie d'une classe, je m'y prends bien, non ?
    Parce que sinon je ne comprends pas comment je peux faire !

    D'autre part je compte distribuer cette DLL pour qu'elle puisse etre attaquée avec plusieurs langages, donc si j'ai bien compris le .lib n'est pas vraiment adapté.

    Et comme j'utilise un .def, j'ai compris que je n'avais pas besoin de déclarer mes fonctions en "extern C ..."

  11. #11
    Membre éprouvé
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Points : 1 067
    Points
    1 067
    Par défaut
    Quand tu ouvres ta DLL avec un outil te permettant de voir les méthodes exportées (comme Depends), quelles sont les siennes?
    Je pense que ton problème vient de la déclaration de la fonction exportée. Le lien donné par Farscape de tonne tous les mots clés nécessaires.

  12. #12
    Membre actif

    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2003
    Messages
    286
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 286
    Points : 255
    Points
    255
    Par défaut
    Si je l'ouvre avec Depends ou PEiD voila les infos de ma dll de l'exemple 2 :

    Ordinal : 00001
    RVA : 000016F0
    Offset : 000000AF0
    Name : LancePaiement

    Tout à l'air bon, d'ailleurs il n'y a pas de raisons du contraire.

    La méthode de farscape est une méthode qui utilise des .lib, et moi j'utilise des .def.
    Le truc c'est que je souhaite que cette DLL puisse être appellée depuis vb.net, c++ 6.0 ... Donc je ne pense pas que les .lib soient une solution.


  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    391
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 391
    Points : 347
    Points
    347
    Par défaut
    Bonjour

    J'utilise la meme facon que toi, c'est a dire exportée une fonction en dehors de la classe avec un .def

    Par contre je definis ma fonction dans le .h just en dessous des include de la facon suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    extern "C" __declspec(dllexport) int ResetduDSP(int SrPortNo);
    dans le . cpp ma fonction s'ecrit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int ResetduDSP(int Port)
    {
    	AFX_MANAGE_STATE(AfxGetStaticModuleState());
    	CString strbis; .......
    et le .def
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ; GetRfidTagList.def : Declares the module parameters for the DLL.
     
    LIBRARY      "GetRfidTagList"
     
    EXPORTS
        ; Explicit exports can go here
     
     
    	ResetduDSP			@1

    cordialement

  14. #14
    Membre actif

    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2003
    Messages
    286
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 286
    Points : 255
    Points
    255
    Par défaut
    au fait merci pour ta réponse

    Tu arrives à déboguer ta dll sans soucis ?

Discussions similaires

  1. Réponses: 1
    Dernier message: 24/04/2007, 09h27
  2. variable globale dans une dll MFC
    Par loup_precaire dans le forum MFC
    Réponses: 4
    Dernier message: 12/09/2006, 11h22
  3. [VB6] Débugage d'une DLL Active X
    Par drinkmilk dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 19/05/2006, 14h49
  4. [MFC] Problèmes d'inclusion d'une DLL
    Par CaptnB dans le forum MFC
    Réponses: 1
    Dernier message: 12/05/2006, 18h01
  5. [MFC ]Probleme de linkage d'une dll
    Par Lysis dans le forum MFC
    Réponses: 9
    Dernier message: 22/01/2004, 14h51

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