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

Langage Delphi Discussion :

Appel d'une fonction dans une DLL


Sujet :

Langage Delphi

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Appel d'une fonction dans une DLL
    avec :
    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
    procedure TForm4.Button1Click(Sender: TObject);
    var
      hDLL: THandle;
      Somme: TDLLSomme;
      a,b: double;
    begin
      hDLL:= LoadLibrary(pChar(DLLName));
      if (hDLL < HINSTANCE_ERROR) then
           raise Exception.Create(DLLName + 'erreur au chargement de la DLL' + SysErrorMessage(GetLastError));
      try
        @Somme:=GetProcAddress(hDLL,'Add');
        if Assigned(Somme) then
        begin
          a:= 2.5;
          b:= 1.5;
          label1.Caption:= FloatToStrF(Somme(a,b),ffFixed,5,2);
        end;
      finally
        FreeLibrary(hDLL);
      end;
    end;
    la fonction Somme n'est pas assignée alors que la DLL a été chargée.
    Les fonctions de la DLL ont été développées en VC avec le code suivant :
    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
    #include "stdafx.h"
        class MyMathFuncs
        {
        public:
            // Returns a + b
            static __declspec(dllexport) double Add(double a, double b);
     
            // Returns a - b
            static __declspec(dllexport) double Subtract(double a, double b);
     
            // Returns a * b
            static __declspec(dllexport) double Multiply(double a, double b);
     
            // Returns a / b
            // Throws DivideByZeroException if b is 0
            static __declspec(dllexport) double Divide(double a, double b);
        };
    Où est l'erreur ?

  2. #2
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Bonjour,
    Citation Envoyé par colorid Voir le message
    Où est l'erreur ?
    Je dirais qu'elle est dans le type TDLLSomme qui n'est pas indiqué...
    Ce devrait resembler à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // static __declspec(dllexport) double Add(double a, double b);
    TDllsomme = function(a, b: Double): Double; cdecl;
    Philippe.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut J'avais oublié...
    Avant la procedure TForm4.Button1Click je déclare :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    const
      DLLName = 'DLLTestVC.dll';
     
    function Add(a,b:double):double; stdcall; external DLLName;
     
     
    type
      TDLLSomme = function (param1,param2: double): double;

  4. #4
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Il y a un gros micmac.
    Vous avez déclaré la dll et sa fonction de manière statique et dans la procédure, vous la rappelez de manière dynamique...
    De 2 choses l'une :
    1. Appel statique :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      const
        DLLName = 'DLLTestVC.dll';
       
      function Add(a, b: Double): Double; cdecl; external DLLName;
       
      // Dans la procédure, pas de LoadLibrary ni de GetProcAdress:
        label1.Caption:= FloatToStrF(Add(a, b), ffFixed, 5, 2);
    2. Appel dynamique :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      type
        TDLLSomme = function (param1, param2: Double): Double; cdecl;
       
      // Dans la procédure, appel à LoadLibrary, GetProcAdress, etc


    Ne pas oublier le type d'appel cdecl...
    Philippe.

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Ok j'ai corrigé mais sans résultat
    Correction :
    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
    const
      DLLName = 'DLLTestVC.dll';
     
    //function Add(a,b:double):double; stdcall; external DLLName;
     
     
    type
      TDLLSomme = function (param1,param2: double): double; cdecl;
     
     
    procedure TForm4.Button1Click(Sender: TObject);
    var
      hDLL: THandle;
      Somme: TDLLSomme;
      a,b: double;
    begin
      hDLL:= LoadLibrary(pChar(DLLName));
      if (hDLL < HINSTANCE_ERROR) then
        raise Exception.Create(DLLName + 'erreur au chargement' +
                                SysErrorMessage(GetLastError));
      try
        @Somme:=GetProcAddress(hDLL,'Add');
        if Assigned(Somme) then
        begin
          a:= 2.5;
          b:= 1.5;
          label1.Caption:= FloatToStrF(Somme(a,b),ffFixed,5,2);
        end else ShowMessage('La fonction "Add" n''a pas été trouvée dans la DLL');
      finally
        FreeLibrary(hDLL);
      end;
    end;
    Résultat à l(exécution : 'La fonction "Add" n''a pas été trouvée dans la DLL'

  6. #6
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Que donne comme rapport un outil comme "DLL Export Viewer" ?
    Cela devrait ressembler à ceci et permettre de connaitre le nom del afonction exportée :
    ==================================================
    Function Name : Add
    Address : 0x12345678
    Relative Address : 0x00001234
    Ordinal : 12 (0xc)
    Filename : dlltestvc.dll
    Full Path : C:\MyDll\dlltestvc.dll
    Type : Exported Function
    ==================================================
    Aussi, je vois dans le code VC une syntaxe class { }. Classe d'objet C++ ?
    Philippe.

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Essai avec DLL développée en Delphi
    Je viens d'essayer avec une DLL développée sous Delphi avec les mêmes fonctions : A la ligne 27 quand il exécute la fonction il se plante avec "Access violation at.."

  8. #8
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    Citation Envoyé par colorid Voir le message
    Je viens d'essayer avec une DLL développée sous Delphi avec les mêmes fonctions : A la ligne 27 quand il exécute la fonction il se plante avec "Access violation at.."
    avec la même convention d'appel dans la DLL et l'EXE ?
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Voila les prototypes de la DLL en Delphi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    function Add(const a,b: double):double; stdcall; export;
    function Subtract(const a,b: double):double; stdcall; export;
    function Multiply(const a,b: double):double; stdcall; export;
    function Divide(const a,b: double):double;stdcall; export;

  10. #10
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Et les définitions et conventions d'appel côté exécutable ? elles sont les mêmes ?
    Philippe.

  11. #11
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    Citation Envoyé par Ph. B. Voir le message
    Et les définitions et conventions d'appel côté exécutable ? elles sont les mêmes ?
    dans l'exemple plus haut c'est du cdecl, alors forcément ça coince

    NB: le mot clé export n'est plus nécessaire depuis Delphi 2

    Les directives near, far et export désignent des conventions d'appels utilisées dans la programmation Windows 16 bits. Elles sont sans effet dans les applications 32 bits et sont conservées uniquement dans un souci de compatibilité ascendante.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

Discussions similaires

  1. Appel d'une fonction dans une fonction d'une même classe
    Par script73 dans le forum Général Python
    Réponses: 3
    Dernier message: 06/03/2015, 10h18
  2. Réponses: 6
    Dernier message: 02/11/2011, 09h34
  3. portée d'une variable dans une fonction dans une méthode
    Par laurentg2003 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 29/06/2009, 19h05
  4. Appel d'une fonction dans une fonction (sql server 2005)
    Par catchouse dans le forum Développement
    Réponses: 10
    Dernier message: 06/05/2009, 12h03
  5. Appeler une fonction dans une fonction
    Par bryanstaubin dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 18/06/2007, 09h39

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