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

Code::Blocks Discussion :

Compiler une dll pour Excel VBA


Sujet :

Code::Blocks

  1. #1
    Membre habitué
    Inscrit en
    Janvier 2004
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 173
    Points : 127
    Points
    127
    Par défaut Compiler une dll pour Excel VBA
    Bonjour à tous,

    une question qui est entre du C++ et du VBA (j'ai choisi de la mettre ici) :
    Je veux compiler une dll pour l'utiliser ensuite en VBA sous Excel. C'est la première fois que je fais ça et je veux juste assimiler le principe avec un exemple très simple.

    J'ai créé un projet sous code block. Voici mon .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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #ifndef __MAIN_H__
    #define __MAIN_H__
     
    #include <windows.h>
     
    /*  To use this exported function of dll, include this header
     *  in your project.
     */
     
    #ifdef BUILD_DLL
        #define DLL_EXPORT __declspec(dllexport)
    #else
        #define DLL_EXPORT __declspec(dllimport)
    #endif
     
     
    #ifdef __cplusplus
    extern "C"
    {
    #endif
     
    int DLL_EXPORT carre(int chiffre);
     
    #ifdef __cplusplus
    }
    #endif
     
    #endif // __MAIN_H__
    et voici mon .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
    #include "main.h"
     
    // a sample exported function
    int DLL_EXPORT carre(int chiffre)
    {
        return chiffre*chiffre;
    }
     
    extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
        switch (fdwReason)
        {
            case DLL_PROCESS_ATTACH:
                // attach to process
                // return FALSE to fail DLL load
                break;
     
            case DLL_PROCESS_DETACH:
                // detach from process
                break;
     
            case DLL_THREAD_ATTACH:
                // attach to thread
                break;
     
            case DLL_THREAD_DETACH:
                // detach from thread
                break;
        }
        return TRUE; // succesful
    }
    Je compile ma dll, ça a l'air de fonctionner. Je vais sous Excel et je déclare dans un module :

    Option Explicit

    Private Declare Function carre Lib "C:\Users\Nicolas\Desktop\DLL C++\TestDLL\bin\Release\TestDLL.dll" (ByVal chiffre As Integer) As Integer

    Sub toto()
    Debug.Print carre(10)
    End Sub

    J'obtiens l'erreur 49 :

    Convention d'appel de dll incorrecte

    J'ai tenté de changer le type des variables en double dans les deux (C et VBA), mais sans succès. Est ce que quelqu'un peut me dire d'où vient le problème ?

    Je vous remercie

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Les fonctions exportées doivent avoir la convention d'appel __stdcall (elles sont en __cdecl par défaut).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DLL_EXPORT int __stdcall carre(int chiffre);
    PS: Pense à donner un nom plus explicite que "DLL" dans DLL_EXPORT et BUILD_DLL; un nom pour lequel le risque de collision soit faible.
    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.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    Bonjour,

    Je viens de tomber sur ce post déjà ancien.
    Il se fait que je suis débutant sur Code::Blocks et que je me pose la même question que ANOVA.
    Je travaille avec Code::Blocks 13.12 et avec Excel 2010 sous Seven 64 bits.

    Sans appliquer le conseil de Médinoc, donc en restant identique à ANOVA, j'obtiens sous VBA la réponse : "Convention d'appel de DLL incorrecte".
    En lançant l'outil Dependency Walker" sur ma DLL, j'obtiens :
    • Hint 0 DllMain@12 Entry Point 0x0001220
    • Hint 1 carre EntryPoint 0x0001214


    En appliquant le conseil de Médinoc, en mettant le __stdcall dans le .h et le .ccp, j'obtiens sous VBA la réponse : "Point d'entrée carre d'une DLL introuvable dans "......dll"".
    En lançant l'outil Dependency Walker" sur ma DLL, j'obtiens :
    • Hint 0 DllMain@12 Entry Point 0x0001220
    • Hint 1 carre@4 EntryPoint 0x0001214


    C'est désespérant !!
    Pourriez-vous m'indiquer la démarche à suivre.
    Je n'ai pas trouvé de tutorial pour créer des DLL pour Excel avec Code::Blocks, uniquement avec Visual C++.

    Je vous remercie pour votre aide.

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Pour exporter une fonction avec son nom non-décoré, il faut faire un fichier .def qu'on passe au linker lors du linkage de la DLL.
    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.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    Bonsoir,

    En fait, j'ai trouvé la réponse sur un autre forum.
    Je vous la livre.

    En reprenant texto le code source proposé par ANOVA, il faut le modifier comme suit :
    • Rajouter __stdcall, aussi bien dans le .h que dans le .cpp
    • dans le .h : int DLL_EXPORT __stdcall carre(int chiffre);
    • dans le .cpp : int DLL_EXPORT __stdcall carre(int chiffre) { .... }


    Tout au moins avec la dernière version de Code::Blocks (13.12), il n'est pas besoin de faire un fichier .def (il est automatiquement réalisé).
    PAR CONTRE, il faut rajouter une option dans Code::Block :
    • Menu Project / Build options / Linker settings / Other linker options
    • Saisir l'option suivante : -Wl,--add-stdcall-alias


    Compiler la DLL et l'utiliser comme indiqué par ANOVA ... et cette fois-ci, ça marche parfaitement, tant dans le VBA que dans les cellules de la feuille Excel.

    Autre subtilité :
    Dans l'exemple d'ANOVA, la variable est passée par valeur (int chiffre). Dans le VBA, on déclare le paramètre avec un ByVar dans le VBA.
    Si l'on veut passer le paramètre par référence, on indiquer (int & chiffre) dans le .h et le .cpp, et on déclare le paramètre avec ByRef dans le VBA.


    Bonne soirée.
    On peut donc clôturer ce post.

Discussions similaires

  1. Creer un Add-in ou une .dll pour Excel/VBA
    Par funtim78 dans le forum C#
    Réponses: 4
    Dernier message: 31/05/2014, 16h05
  2. Réponses: 0
    Dernier message: 21/01/2011, 10h14
  3. Réponses: 3
    Dernier message: 07/07/2009, 17h17
  4. Réponses: 4
    Dernier message: 02/09/2005, 11h24
  5. [DLL] Utilisation d'une DLL pour utiliser serveur Firebird
    Par sekiryou dans le forum Bases de données
    Réponses: 2
    Dernier message: 11/08/2004, 15h20

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