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éation dll


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 129
    Par défaut Problème création dll
    Bonjour,

    Je suis actuellement en train de créer une dll qui gère la connexion et la communication avec un périphérique USB. Cette dll ne contient que des fonctions, pas de classe, et elle est exploitée par un programme test : une IHM C++/Qt.

    Ma "dll" est compilée avec gcc et je mets des extern "C" englobant la déclaration de mes fonctions dans le header le .cpp.

    Il se passe quelque chose d'étrange :

    Une fonction de la dll provoque un comportement étrange : Son appel depuis l'IHM semble déplacer la mémoire réservée à l'IHM. Je veux dire par la que l'IHM est composée d'une classe simple qui contient des attributs. Une fois l'appel de fonction réalisé, tous les attributs de la classe prennent une valeur aléatoire, tandis que les variables globales ou locales n'appartenant pas à la classe ne sont pas modifiées. C'est même valable pour la valeur prise par un slider et retournée par : slider.value();

    Je ne comprends pas. Evidemment cela fait planter mon appli.

    IHM:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myfunction(class_attribute)
    DLL:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void myfunction(float value) {
        puts(value);
    }
    Ceci affiche un nombre "aléatoire"

    le même affichage après l'appel de fonction dans l'IHM affiche également un nombre aléatoire.

    Quelqu'un a soumis l'hypothèse selon laquelle le problème pouvait venir du caractère dynamique de la librairie qui est utilisée tel un objet dynamique. Qu'en pensez vous ? La plupart des fonctions marche et un programme simple sans IHM semble fonctionner.

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    void myfunction((float value) {
        puts(value);
    }
    Ne devrait pas compiler AFAIK, puisque puts prend en argument une chaine C et non un float. Je suppose donc que ce n'est pas ta vrai signature ou le cvrai code, ce qui ne nous aide pas...

    Sinon, comment est déclarée ton instance de la classe? Variable locale? Ou argument d'une fonction passé par copie? Si c'est le cas, elle est sur la pile ce qui pourrait indiquer une corruption de la pile. As-tu pensé à préciser la convention d'appel dans le header de ta DLL? Parfois on voit un mismatch de la convention d'appel utilisé enrte binaire appelant et DLL, ce qui entraîne une corruption de la pile.

    Quelque chose comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    extern "C"{
    void myfunction(float value) __attribute__ ((stdcall))
    }
    EDIT: stupide faute de frappe, il faut 2 parenthèses imbriquées

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 129
    Par défaut
    Citation Envoyé par therwald Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    void myfunction(float value) {
        puts(value);
    }
    Ne devrait pas compiler AFAIK, puisque puts prend en argument une chaine C et non un float. Je suppose donc que ce n'est pas ta vrai signature ou le cvrai code, ce qui ne nous aide pas...
    Non effectivement, ce n'est pas le code réel, mea culpa.Voici un meilleur extrait du code qui plante

    IHM.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        private:
            int m_var1, m_var2, m_var3, m_var4;
    Ces variables sont initialisées à 0;

    IHM.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    cout << m_var1  << m_var2 << m_var3 << m_var4 << endl;
    myfunction(1, m_var1);
    cout << m_var1  << m_var2 << m_var3 << m_var4 << endl;
    myfunction(2, m_var2);
    myfunction(3, m_var3);
    myfunction(4, m_var4);
    Et par exemple cela m'affiche en sortie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    0000
    -15132513540010651-16106506106

    Citation Envoyé par therwald Voir le message
    Sinon, comment est déclarée ton instance de la classe? Variable locale? Ou argument d'une fonction passé par copie? Si c'est le cas, elle est sur la pile ce qui pourrait indiquer une corruption de la pile.
    Si tu parles de la classe IHM, elle est déclarée de manière non dynamique en local dans mon main.cpp



    Citation Envoyé par therwald Voir le message
    As-tu pensé à préciser la convention d'appel dans le header de ta DLL? Parfois on voit un mismatch de la convention d'appel utilisé enrte binaire appelant et DLL, ce qui entraîne une corruption de la pile.

    Quelque chose comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    extern "C"{
    void myfunction(float value) __attribute__ (stdcall)
    }
    J'essaye de jeter un oeil, mais je suis sur Linux, et cela ne semble pas compiler.

  4. #4
    Membre Expert
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Par défaut
    Citation Envoyé par 0_Azerty_0 Voir le message
    J'essaye de jeter un oeil, mais je suis sur Linux, et cela ne semble pas compiler.
    En bon boulet j'avais oulié une paire e parenthèses (j'ai EDIT le mesasge précédent pour essayer de ne pas induire en erreur)

  5. #5
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 129
    Par défaut
    Mais à quoi cela sert exactement ? Je suis pas à l'aise avec l'idée de pas comprendre ce que je fais !
    Par ailleurs, le extern C doit entourer uniquement les prototypes de fonction ou leur définition également ?

    Sinon, je viens de faire un test qui vient d'exclure le problème de linkage dll : J'ai inclus une copie des fichiers de la dll à mon projet pour voir ce que ca allait donner : Résultat, même erreur ! Il ne s'agit donc plus d'une histoire de dll, mais bien un problème de mémoire désormais !

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Par défaut
    OK, donc si en compilant monolithique le problème subsiste, c'est que ce n'est pas un soucis de DLL boundary, effectivement.
    Pour ce qui est de l'attribut stdcall (ou cdecl), l'explication est la suivante:
    au niveau binaire, l'appelant et l'appelé doivent s'accorder pour la transmission des paramètres et la gestion de la pile. C'est ce qu'on appelle la convention d'appel. Elle est habituellement sous entendu, mais les valeurs par défaut peuvent diverger dans le cas de deux binaires compilés séparément (cas typique exécutable + DLL) et dans ce cas on peut corrompre la pile ou des variables qui sont prises les unes pour les autres...
    Les attributs de convention d'appel permettent de spécifier la convention d'appel sur la fonction pour être sûr que c'est cohérent entre appelant et appelé si la fonction exposée à travers une frontière de DLL.

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

Discussions similaires

  1. CEGUI, Problème création .dll
    Par Erwan28250 dans le forum Ogre
    Réponses: 7
    Dernier message: 17/03/2013, 22h54
  2. Problème création DLL
    Par sniperpro dans le forum Langage
    Réponses: 10
    Dernier message: 05/10/2011, 10h11
  3. Problème Création DLL
    Par Fabien25C dans le forum Débuter
    Réponses: 1
    Dernier message: 25/11/2009, 13h57
  4. Problème création de DLL avec CString
    Par loupdeau dans le forum MFC
    Réponses: 3
    Dernier message: 21/07/2005, 20h55
  5. Problème création de DLL
    Par monsieur.voie.lactee dans le forum C++Builder
    Réponses: 4
    Dernier message: 12/08/2003, 16h56

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