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 en c++ et appel depuis windev


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Septembre 2007
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 86
    Points : 45
    Points
    45
    Par défaut DLL en c++ et appel depuis windev
    Bonjour,
    je n'arrive pas à faire un appel à une fonction avec une dll en c++ voici la source (récupérer depuis le site microsoft)
    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
     
    // MathFuncsDll.h
     
    #ifdef MATHFUNCSDLL_EXPORTS
    #define MATHFUNCSDLL_API __declspec(dllexport) 
    #else
    #define MATHFUNCSDLL_API __declspec(dllimport) 
    #endif
    namespace MathFuncs
    {
        // This class is exported from the MathFuncsDll.dll
        class MyMathFuncs
        {
        public: 
            // Returns a + b
            static MATHFUNCSDLL_API double Add(double a, double b); 
     
            // Returns a - b
            static MATHFUNCSDLL_API double Subtract(double a, double b); 
     
            // Returns a * b
            static MATHFUNCSDLL_API double Multiply(double a, double b); 
     
            // Returns a / b
            // Throws const std::invalid_argument& if b is 0
            static MATHFUNCSDLL_API double Divide(double a, double b); 
        };
    }
    puis
    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
     
    // MathFuncsDll.cpp : Defines the exported functions for the DLL application.
    //
     
    #include "stdafx.h"
    #include "MathFuncsDll.h"
    #include <stdexcept>
     
    using namespace std;
     
    namespace MathFuncs
    {
        double MyMathFuncs::Add(double a, double b)
        {
            return a + b;
        }
     
        double MyMathFuncs::Subtract(double a, double b)
        {
            return a - b;
        }
     
        double MyMathFuncs::Multiply(double a, double b)
        {
            return a * b;
        }
     
        double MyMathFuncs::Divide(double a, double b)
        {
            if (b == 0)
            {
                throw invalid_argument("b cannot be zero!");
            }
     
            return a / b;
        }
    }
    l'appel se fait comme ceci en c++
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MathFuncs::MyMathFuncs::Add(a, b)
    en windev j'essaye
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    toto1 est un réel sur 8 octets
    toto2 est un réel sur 8 octets
    ChargeDLL("xxx.dll")
    nAdresseChaîne est un entier = API("xxx.dll","MathFuncs::MyMathFuncs::Add",toto1,toto2)
    ou
    nAdresseChaîne est un entier = API("xxx.dll","MathFuncs.MyMathFuncs.Add",toto1,toto2)
    rien a faire , quelqu'un à une idée ?

  2. #2
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 476
    Points
    11 476
    Billets dans le blog
    11
    Par défaut
    Je me souviens avoir tenté, et m'être cassé les dents.
    Au final, j'ai choisi la solution de facilité, et ai implémenté un Assembly C#
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  3. #3
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Pourquoi faire des fonctions statiques d'une classe sans contenu?
    Utilise donc des fonctions libres
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  4. #4
    Membre du Club
    Inscrit en
    Septembre 2007
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 86
    Points : 45
    Points
    45
    Par défaut
    merci de vos réponses

    Citation Envoyé par dragonjoker59 Voir le message
    Je me souviens avoir tenté, et m'être cassé les dents.
    Au final, j'ai choisi la solution de facilité, et ai implémenté un Assembly C#
    , j'evite le c# car il faut installer tout un biz en +

    Citation Envoyé par ternel Voir le message
    Pourquoi faire des fonctions statiques d'une classe sans contenu?
    Utilise donc des fonctions libres
    c'est à dire ?

  5. #5
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    remplacer ton code de base:
    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
    namespace MathFuncs
    {
        // This class is exported from the MathFuncsDll.dll
        class MyMathFuncs
        {
        public: 
            // Returns a + b
            static MATHFUNCSDLL_API double Add(double a, double b); 
     
            // Returns a - b
            static MATHFUNCSDLL_API double Subtract(double a, double b); 
     
            // Returns a * b
            static MATHFUNCSDLL_API double Multiply(double a, double b); 
     
            // Returns a / b
            // Throws const std::invalid_argument& if b is 0
            static MATHFUNCSDLL_API double Divide(double a, double b); 
        };
    }
    par ceci:
    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
    namespace MathFuncs
    {
            // Returns a + b
            MATHFUNCSDLL_API double Add(double a, double b); 
     
            // Returns a - b
            MATHFUNCSDLL_API double Subtract(double a, double b); 
     
            // Returns a * b
            MATHFUNCSDLL_API double Multiply(double a, double b); 
     
            // Returns a / b
            // Throws const std::invalid_argument& if b is 0
            MATHFUNCSDLL_API double Divide(double a, double b);
    }
    Qu'est un MyMathFuncs? (a part un plagiat d'un défaut de java, à savoir l'absence de fonctions libres)
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Bizarre que personne n'ait mentionné le mangling C++.
    Même si le code source vient de MSDN, il faut le comprendre avant de l'utiliser.
    Ici, c'est assez piègeux, car c'est faussement simple.

    Moi, je suis beaucoup plus radical dans la critique du code de MSDN qu'@ternel.
    @ternel critique le fait de ne pas utiliser des fonctions libres, mais en fait, c'est le fait de faire une API C++ qui est merdique.
    Le C++ n'a pas normalisé la décoration des symboles que les modules exportent.
    Donc, en utilisant une API C++, vous générez un module qui n'est facilement utilisable QUE par la MÊME chaine de compilation (compilateur + éditeur de lien) qui a généré le module binaire (ici la Dll).
    Donc, l'exemple de MSDN, c'est uniquement dans le monde merveilleux où tout le monde utilise la même version du compilateur, avec les même options de compilations qu'il est opérationnel.
    Donc, avec votre utilisation de WinDev, vous êtes clairement sortie de ce monde merveilleux et vous vous êtes mangé un poteau en travers du casque.

    Si vous voulez vraiment voir l'envers du décor de pacotille, utilisez un outils comme Dependency Walker ( http://www.dependencywalker.com/ ) pour voir la tête des noms exportés par MSVC.
    Cela ne sera clairement pas "MathFuncs::MyMathFuncs::Add", mais une horreur avec tout plein de "?", "_" et autres "@".
    Il s'agira du mangling C++ (décoration des noms) utilisé par MSVC et compris nativement que par MSVC.

    Si vous ne voulez pas faire toutes ces acrobaties (et ne les faites pas), il serait largement plus simple de faire une Dll exportant une interface C et non C++.
    Dans votre cas, c'est très simple, car l'utilisation de namespace ou de classe ne se justifie pas, comme l'indique @ternel.

    En reprenant le code de @ternel

    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
    extern "C"
    {
            // Returns a + b
            MATHFUNCSDLL_API double Add(double a, double b); 
     
            // Returns a - b
            MATHFUNCSDLL_API double Subtract(double a, double b); 
     
            // Returns a * b
            MATHFUNCSDLL_API double Multiply(double a, double b); 
     
            // Returns a / b
            // Throws const std::invalid_argument& if b is 0 -> NON
    // API C donc pas d'exception, retournez un NaN ou autres bidules de la norme IEEE de nombre à virgule flottante
            MATHFUNCSDLL_API double Divide(double a, double b);
    }
    idem pour le .cpp, ajoutez extern "C"{...} autour des implementations de ces fonctions libres.

    En utilisant Dependency Walker, vous verrez que les noms des symboles exportés par la Dll avec une interface C seront bien plus "simple".

    Si tout est correctement exporté par le Dll et que WinDev support bien une Interface C, le WinDev code serait un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ChargeDLL("xxx.dll")
    nAdresseChaîne est un entier = API("xxx.dll","Add",toto1,toto2)

  7. #7
    Membre du Club
    Inscrit en
    Septembre 2007
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 86
    Points : 45
    Points
    45
    Par défaut
    merci becelar et ternel
    je vais faire ceci sans prendre de poteau dans le casque
    je vais surtout essayer Dependency Walker avec ma dll , j'aime bien le nom déjà lol

  8. #8
    Membre du Club
    Inscrit en
    Septembre 2007
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 86
    Points : 45
    Points
    45
    Par défaut
    effectivement Dependency Walker fonctionne très bien , c'est dommage que l'on ne sache pas ce que la fonction attends comme paramètre ni combien .

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    c'est dommage que l'on ne sache pas ce que la fonction attends comme paramètre ni combien .
    Et bien si !!!
    Enfin, le truc tout abscons du mangling C++, c'est de foutre tout plein de caractères bizarres pour que les outils C++ puis récupérer cette information : La signature du machin.
    Le problème du mangling C++, c'est juste que les éditeurs de compilateur/linker ne se sont pas mis d'accord sur comment mettre ces caractères.
    Résultat, la chaine "décorée" du symbole sera incompréhensible (voir mal comprise) pour une autre compilateur/linker que celui qui là généré.
    Je crois que Dependency Walker a un bouton "C++" qui fait le décodage des noms décorés vers la signature à la C++ en utilisant l'hypothèse que c'est VS qui a généré ce noms à coucher dehors.
    L'utilitaire "undname" permet de faire la même chose dans une console. (dumpbin pour avoir des infos sur la Dll en ligne de commande.

    Article d'explications :
    https://msdn.microsoft.com/en-us/lib...or=-2147217396

    En C, là effectivement, comme indiqué dans l'article, les informations sont beaucoup beaucoup plus light. Mais suffisant pour ne pas faire n'importe quoi lors d'un appel C.

    Il faudrait voir du côté de WinDev si vous ne disposez pas d'outils pour générer automatiquement du code de glue entre Windev et une Dll avec une API C, car c'est un cas extrêmement fréquent d'interopérabilité.

    En C ou en C++, pour avoir un appel aussi simple qu'un appel "local" pour un appel d'une fonction dans une Dll, il suffit de faire un "#include" du .h contenant la définition toutes les méthodes exportées par la dll, ajouter le .lib généré en même temps que la Dll par VS à la liste des librairies en entré du linker et le tour est joué. => Vérification que l'appel correspond à la signature + configuration automatique des dépendances entre l'exe et la Dll + etc...

    Donc, cherchez dans la documentation de WinDev si vous ne pouvez pas disposer du même confort plutôt que d'utiliser ces trucs tout vieux que sont "ChargeDLL" et "API" (il y a les même en C et en C++ : LoadLibrary et GetProcAdress et c'est tout moisi).

  10. #10
    Membre du Club
    Inscrit en
    Septembre 2007
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 86
    Points : 45
    Points
    45
    Par défaut
    bonsoir ,
    j'ai essayer undname mais sans réel résultat , d'ailleurs j'ai pas bien compris la manip , pour Dependency Walker et le bouton "C++" ,il ne donne rien de spécifique ou alors il y a une manipulation elle aussi spécifique .
    Pour windev , en dehors de chargeDLL et api , je n'ai jamais rien vu d'autre ...

  11. #11
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,
    Sous dependency walker, après avoir sélectionné ta dll, les fonctions exportées sont indiquées dans la colonne "functions". Dans cet exemple ce sont BaseThreadInitThunk et InterlockedPushListSList.
    Nom : dependency_walker.png
Affichages : 954
Taille : 24,8 Ko
    Le demangling C++ doit être désactivé pour voir le nom "brut" à utiliser. Dans ces noms il y a Add, Substract, ... Ce sont ces noms qu'il faut utiliser.
    S'il n'y a rien c'est que ta dll n'exporte pas tes fonctions, avant #include "MathFuncsDll.h" il faut un #define MATHFUNCSDLL_EXPORTS

  12. #12
    Membre du Club
    Inscrit en
    Septembre 2007
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 86
    Points : 45
    Points
    45
    Par défaut
    merci dalfab pour ta réponse,
    j'ai bien trouvé les fonctions de ma dll mais pas les paramètres à passer ni combien ,c'est çà que je disais dans mon dernier poste ,c'était juste un constat

Discussions similaires

  1. [C#] DLL C# Appelée depuis Windev
    Par loic18 dans le forum Débuter
    Réponses: 0
    Dernier message: 07/02/2014, 16h08
  2. Réponses: 2
    Dernier message: 19/05/2009, 10h53
  3. OpenGL appelé depuis une DLL perd son contexte
    Par sopsag dans le forum OpenGL
    Réponses: 7
    Dernier message: 27/10/2008, 12h39
  4. Installaton de dll et appel depuis Excel
    Par LittleDev dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 03/03/2008, 21h11
  5. Réponses: 4
    Dernier message: 01/06/2006, 15h55

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