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 :

probleme appel de fonction dans une DLL


Sujet :

C++

  1. #1
    Membre habitué Avatar de sylvain.cool
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 242
    Points : 158
    Points
    158
    Par défaut probleme appel de fonction dans une DLL
    Bonjour,

    Je souhaite charger un DLL dans mon programme et appeller une fonction contenu dans celle-ci.
    Pour l'instant, je fais ça :
    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
    	AnsiString texte;
    	TPath path;
     
    	texte = "C:\\PJ_Octopus_V1.0\\Source\\bin\\plugins\\PLG_SimplePlugin\\Technics\\TCH_Brillance\\TCH_Brillance.dll";
     
    	//texte = "C:\\msimusic.dll";
    	path = texte;
    	cout << path.toString().c_str() << endl; 
     
    	if(path.isValidPath())
    	{
    		//chargement du plugin
    		HINSTANCE hDLL;
    		DLL_TECHNIC_FUNC_TYPE callFunction;	  	
    		hDLL = LoadLibrary(path.toString().c_str());  
     
    		if(hDLL == NULL)
    		{     
    			texte = "hDLL: ";
    			texte += (int)hDLL;
    			cout << texte.c_str() << endl; 
    			texte = "TObjetRunImpl::loadProcess-> erreur loadLibrary";
    			cout << texte.c_str() << endl; 
    			HRESULT reponse = GetLastError(); 
    			texte = "Error: ";
    			texte += reponse;
    			cout << texte.c_str() << endl; 
    			analyseReponse(reponse, "loadLibrary");
    		}
    		else
    		{  
    			callFunction = (DLL_TECHNIC_FUNC_TYPE) GetProcAddress(hDLL, DLL_TECHNIC_FUNC_NAME.c_str());
    			//callFunction = (void *) GetProcAddress(hDLL, DLL_TECHNIC_FUNC_NAME.c_str());
    			if(callFunction == NULL)
    			{         
    				texte = "TObjetRunImpl::loadProcess-> "+ERROR_TECHNIC_FUNCTION;
    				cout << texte.c_str() << endl; 
    				FreeLibrary(hDLL);
    			}
    			else
    			{   
    				ITechnic *technic = callFunction();
    			}
    		}
    	}
    	else
    	{
    		texte = "TObjetRunImpl::loadProcess-> "+ERROR_TECHNIC_FILE;
    		cout << texte.c_str() << endl; 
    	}	
     
        system("PAUSE");
     
    	return 0;
    Le loadLibrary passe bien et me renvoi une DLL.

    Le GetProcAddress à l'air de trouver la fonction puisque il me renvoi un pointeur non NULL.

    Par contre, quand j'essaie d'exécuter la fonction, j'ai une violation d'accès.
    J'ai essayer le mode debug pas-à-pas en rentrant dans la fonction callFunction, mais dès que j'essaie de rentrer dedans, j'ai violation d'accès.

    Une idée?

  2. #2
    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 : 61
    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
    Points : 50 367
    Points
    50 367
    Par défaut
    Je ne voie pas la déclaration de callFunction dans ton code (mais ce n'est pas très grave, je suppose qu'elle est déclarée et qu'elle a le bon type)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ITechnic *technic = callFunction();
    Es-tu sûr qu'il ne faut pas de paramètres à cette fonction ?
    Es-ce que tu peux montrer la définition de DLL_TECHNIC_FUNC_TYPE ? C'est un pointeur de fonction mais plus précisemment ?

    Es-ce que tu arrive à entrer dans la fonction avec le debugger (es-ce que tu voies le code) ?
    Ou bien tu ne peux pas rentrer dedans car tu n'as pas les infos de debug de cette fonction et de cette DLL
    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
    .

  3. #3
    Membre habitué Avatar de sylvain.cool
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 242
    Points : 158
    Points
    158
    Par défaut
    Voici la définition de DLL_TECHNIC_FUNC_TYPE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef ITechnic* (*DLL_TECHNIC_FUNC_TYPE)();
    Je suis quasi certain que la fonction ne demande pas de paramètres.

    Quand j'utilise le debugueur, je ne peux pas rentrer dans la fonction car il me dit de suite violation d'accès; avant que j'arrive à la première ligne de cette fonction.

    En fait, je m'inspire d'un programme qui utilise cette DLL et appelle cette fonction. Sur celui-ci, ça marche très bien. Mais sur mon prog, non.

  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 : 61
    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
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par sylvain.cool Voir le message
    Je suis quasi certain que la fonction ne demande pas de paramètres.
    Es-ce que tu peux en être sûr à 100% ?

    Peux tu rajouter ce code avant d'appeler ta fonction pour afficher le nom recherchée par GetProcAddress() de la fonction ainsi que son adresse (juste pour être sûr)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    printf("%s = %.8x\n", DLL_TECHNIC_FUNC_NAME.c_str(), callFunction);
    ITechnic *technic = callFunction();
    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 habitué Avatar de sylvain.cool
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 242
    Points : 158
    Points
    158
    Par défaut
    Voici le code la fonction que j'essaie d'appeller :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    extern "C" ITechnic* __declspec(dllexport) getTechnic()
    {
        return new LesionsTechnic();
    }
    => Pas de paramètres.

    J'ai rajouté la ligne que tu m'a demandé.
    Voici ce que ça m'affiche :
    _getTechnic = 00c1b59c
    J'ai la même adresse dans le debugueur (heureusement).

  6. #6
    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 : 61
    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
    Points : 50 367
    Points
    50 367
    Par défaut
    Je ne suis pas sûr que :
    extern "C" ITechnic* __declspec(dllexport) getTechnic()
    soit équivalent à :
    typedef ITechnic* (*DLL_TECHNIC_FUNC_TYPE)();
    au niveau des conventions d'appel.

    j'essairai bien un :
    typedef ITechnic* (_cdecl *DLL_TECHNIC_FUNC_TYPE)();
    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
    .

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Cela voudrait dire que le projet qui utilise la DLL n'utilise pas les paramètres, par défaut, puisque par défaut, toute fonction ou pointeur de fonction est __cdecl s'il n'est pas spécifiquement autre chose.

    D'un autre côte, une fonction de DLL n'est pas supposée être __cdecl. Par convention, on les déclare plutôt en __stdcall (ainsi que les pointeurs de fonction correspondants)...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre habitué Avatar de sylvain.cool
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 242
    Points : 158
    Points
    158
    Par défaut
    C'est bon, ça passe... enfin je peux rentrer avec le debugueur dans la fonction.

    Par contre, j'ai toujours ma violation d'accès. Mais je devrais m'en sortir avec le debugueur.

    J'ai l'impression qu'il plante à :
    Dois y avoir des problèmes de constructeur dessous.
    Allez je m'enfonce dans le code.

  9. #9
    Membre habitué Avatar de sylvain.cool
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 242
    Points : 158
    Points
    158
    Par défaut
    J'ai oublié de remercier ram_0000.

    MERCI RAM_0000.

  10. #10
    Membre habitué Avatar de sylvain.cool
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 242
    Points : 158
    Points
    158
    Par défaut
    Pour ce que dit Médinoc, le code de la dll n'est pas de moi, et je ne pense y toucher.

    Après, j'avoue que ces notions de __cdecl et de __stdcall me sont totalement étrangères.

  11. #11
    Membre habitué Avatar de sylvain.cool
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 242
    Points : 158
    Points
    158
    Par défaut
    Si je suis dans un constructeur et que le programme plante au niveau de l'accolade :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    LesionsGraphicControl::LesionsGraphicControl()
    { -> Avec debug, ça plante ici
     
    }
    Ça veut dire quoi?

    Normalement, il devrait entrer dans les constructeurs des objets membres non?
    Mais là, il ne le fait pas.
    Ça pourrait être du au fait que ces constructeur sont ds d'autres DLL que je n'ai pas chargé???

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Disons pour résumer, que __cdecl est la convention d'appel C, et __stdcall est la convention d'appel Pascal.

    Sachant que le standard pour Windows et les DLLs, c'est la convention Pascal. Un programme en Visual Basic ne peut pas appeler de fonctions __cdecl, par exemple.

    Par contre, les fonctions de la bibliothèque standard C sont en __cdecl, et il est impossible de faire une fonction à nombre d'arguments variables (comme printf()) en __stdcall.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #13
    Membre habitué Avatar de sylvain.cool
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 242
    Points : 158
    Points
    158
    Par défaut
    Aïe, en fait c'est normal.

    La classe LesionsGraphicControl est associé à des éléments de l'IHM du logiciel.
    Comme moi je fais un serveur qui n'a pas cette interface, ça plante!

    Désolé de vous avoir dérangé pour rien et merci.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 12/09/2012, 10h12
  2. Type d'argument pour appel de fonction dans une DLL
    Par Lio590 dans le forum API, COM et SDKs
    Réponses: 3
    Dernier message: 06/07/2011, 16h28
  3. [WD15] Appel de fonctions dans une DLL
    Par thierrybatlle dans le forum WinDev
    Réponses: 11
    Dernier message: 12/02/2010, 01h46
  4. Appel de fonction dans une DLL
    Par vtk37 dans le forum Windows Forms
    Réponses: 3
    Dernier message: 30/04/2009, 08h58
  5. [ARM] Appel d'une fonction dans une dll
    Par mosfet dans le forum Autres architectures
    Réponses: 3
    Dernier message: 28/03/2007, 08h15

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