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

Delphi Discussion :

Problème de chargement de fonction dans dll dynamique


Sujet :

Delphi

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 76
    Points : 31
    Points
    31
    Par défaut Problème de chargement de fonction dans dll dynamique
    Bonjour,

    je reviens vers vous car j'ai créé une dll à chargement et à liaison dynamique
    voici mon code :

    code :
    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
    function LierFonction(DLL: String; var HandleDLL: THandle; NomFct: String; IndexFct: Integer = -1): Pointer;
    begin
      //Valeurs de retour par défaut
      Result := nil;
      HandleDLL := 0;
     
      //Chargement de la DLL. On récupère son handle
      HandleDLL := LoadLibrary(pAnsiChar(DLL));
     
      //Si le chargement a échoué, on sort
      If HandleDLL = 0 then
        Exit;
     
      //On récupère l'adresse de la fonction voulue, que l'on renvoie
      If IndexFct < 0 then //Si l'index est négatif on utilise le nom sous forme de chaîne
        Result := GetProcAddress(HandleDLL, pAnsiChar(NomFct))
      else                  
        //Sinon, on utilise l'index comme identifiant
        Result := GetProcAddress(HandleDLL, pAnsiChar(IndexFct));
    end;
     
    procedure TForm1.btnSommeClick(Sender: TObject);
    var HandleDLL: THandle; //Pour stocker le handle de la DLL chargée
        Somme    : function(A, B: integer): integer; stdcall; //Notre fonction, sous forme de variable
    begin
      //On récupère le pointeur sur notre fonction nommée 'Somme' au sein de DLL1.dll
      Somme := LierFonction('DLL1.dll', HandleDLL, 'Somme');
     
      //Si Somme a bien reçu un pointeur valide sur une fonction
      If assigned(Somme) then
      try
        //L'appel de la fonction se passe comme avec une fonction ordinaire
        ShowMessageFmt('%d + %d = %d', [A.Value, B.Value, Somme(.Value, B.Value)]);
      finally
    //Ne pas oublier de libérer la DLL lorsqu'elle n'est plus nécessaire
        FreeLibrary(HandleDLL);
      end
      else
        //Sinon, on affiche un message d'erreur : appeler Somme provoquerait une violation d'accès
        ShowMessage('Erreur de chargement de la fonction "Somme"');
    end;
    où ai-je péché ?
    je tourne et retourne mais je ne vois pas mon erreur dans mon dode ?
    merci de me venir en aide s.v ???
    Version Delphi utilisé : Rad Studio Alexandria.

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Version de Delphi car PAnsiChar et String, cela n'est plus compatible à partir de D2009, XE ...

    La Dll contient bien "Somme" dans la section Exports ? voir TDump ou Dependency Walker

    Après HandleDLL étant passé en var, faudra revoir pour l'utiliser si il est déjà défini pour lier plusieurs fonctions de suite
    Personnellement, j'ai bien faire une classe qui encapsule la DLL, le Create et Destroy respecte charge et décharge la DLL, les méthodes récupère l'adresse de la fonction (et la stocke) et l'invoque.
    Le code d'utilisation est ainsi bien propre.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 76
    Points : 31
    Points
    31
    Par défaut Problème chargement de ma fonction somme dans ma dll
    Bonjour,

    Merci d'avoir répondu :
    voici le code de ma Library :
    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
    library Dll1;
     
    { Remarque importante sur la gestion mémoire de la DLL : ShareMem doit être la
      première unité de la clause USES de votre bibliothèque ET la clause USES
      (sélectionner Projet-Voir le source) de votre projet si votre DLL exporte toute procédure ou
      fonction qui passe des chaînes par le biais de paramètres ou de résultats de fonctions. Cela
      s'applique à toutes les chaînes passées vers et depuis votre DLL -- même celles qui
      sont imbriquées dans des enregistrements et des classes. ShareMem est l'unité d'interface au
      gestionnaire de mémoire partagée BORLNDMM.DLL, qui doit être déployé
      avec votre DLL. Pour éviter l'emploi de BORLNDMM.DLL, passez des informations chaîne
      par le biais de paramètres PChar ou ShortString. }
     
    uses
      System.SysUtils,
      System.Classes;
     
    {$R *.res}
     
    function somme(A, B: integer): integer; stdcall;  export;//non obligatoire
    begin
      Result := A + B;
    end;
     
    exports//celle-ci l'est
    somme;
     
    begin
    end.
    Version Delphi utilisé : Rad Studio Alexandria.

  4. #4
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 685
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    PAnsiChar sur LoadLibrary, sûr que ça ne compile pas !
    GetProcAddress qui accepte les deux variantes (PChar,PAnsiChar) va compilé mais échoué pour la raison invoquée par ShaiLeTroll.
    Il y a aussi une erreur à la ligne 33 .Value.

    Le dernier problème est que pour une fois Delphi est case-sensitive (par obligation) ; le nom de la procédure\fonction importée doit correspondre précisément à la déclaration de la clause exports de la DLL. Somme n'étant pas égal à somme...

    Citation Envoyé par ShaiLeTroll Voir le message
    voir TDump ou Dependency Walker
    Ou Ctrl+Alt+M dans l'IDE en débogue.


    Citation Envoyé par Monromero1 Voir le message
    où ai-je péché ?
    La prochaine fois, soit un peu plus précis sur l'erreur rencontrée s'il te plaît

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 76
    Points : 31
    Points
    31
    Par défaut Problème de chargement sur fonction somme dans Rad Studio
    Citation Envoyé par Andnotor Voir le message
    PAnsiChar sur LoadLibrary, sûr que ça ne compile pas !
    GetProcAddress qui accepte les deux variantes (PChar,PAnsiChar) va compilé mais échoué pour la raison invoquée par ShaiLeTroll.
    Il y a aussi une erreur à la ligne 33 .Value.

    Le dernier problème est que pour une fois Delphi est case-sensitive (par obligation) ; le nom de la procédure\fonction importée doit correspondre précisément à la déclaration de la clause exports de la DLL. Somme n'étant pas égal à somme...



    Ou Ctrl+Alt+M dans l'IDE en débogue.



    La prochaine fois, soit un peu plus précis sur l'erreur rencontrée s'il te plaît
    Ok bien compris pour les explications

    bon, y a du boulot !

    J'ai déjà remplacé pAnsiChar
    par PChar,

    2) je vais regarder attentivement les points que vous soulevez
    mais pouvez-vous développer un peu plus, je vous site
    "quant à la ligne 33 .value"
    que dois-je remplacer à cette ligne ?

    3) le plus terrible est que la compilation s'effectue sans erreur
    mais à l'affichage le programme indique impossible de charger la fonction somme
    sans autres erreurs
    alors quand vous me demandez de préciser un peu plus la nature de l'erreur
    vous comprendrez que c'est pas possible dans ce cas de figure précis !

    que me suggerez-vous pour le pChar qui fonctionne bien avec ma version de Delphi ?
    et pour la ligne 33
    j'aimerai un peu plus de précision !
    que me proposez-vous par exemple ?
    pour le reste je vais corriger mon problème de Case
    Delphi propose de nouvelles adaptations auquelles je ne suis pas encore habitué
    à commencer par celle que vous évoquiez lors de votre dernier message.
    Je me permets de vous demander
    de développer quand vous décrivez les erreurs, cela me simplifirais la tâche merci.

    Merci pour votre contribution.
    Version Delphi utilisé : Rad Studio Alexandria.

  6. #6
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 857
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 857
    Points : 11 291
    Points
    11 291
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je serais étonné que ça se passe sans message d'erreur explicite si le code soumis au compilateur contient bien texto la ligne 33 reproduite plus haut !
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 76
    Points : 31
    Points
    31
    Par défaut Problème de chargement de la fonction somme dans mon programme
    Citation Envoyé par tourlourou Voir le message
    Bonjour,

    Je serais étonné que ça se passe sans message d'erreur explicite si le code soumis au compilateur contient bien texto la ligne 33 reproduite plus haut !
    Bonsoir,
    Je suis novice en programmation
    et je pensais bien faire.
    Bon, parfait, que me suggériez-vous pour la ligne 33
    sitée plus haut s.v.p.?
    Je cherche à corriger cette ligne
    mais je n'ai guère de proposition
    je sèche aidez-moi, je vous prie ?
    merci
    Version Delphi utilisé : Rad Studio Alexandria.

  8. #8
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 857
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 857
    Points : 11 291
    Points
    11 291
    Billets dans le blog
    6
    Par défaut
    N'y a-t-il pas d'alerte du compilateur sur l'appel à la fonction Somme de la ligne 33 ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Somme( .Value, B.Value)
    NB j'ai ajouté une espace pour améliorer la lisibilité.

    La coquille est soit dans le code, soit dans le copier/coller vers le forum, mais, comme Andnotor, je pense qu'elle est susceptible de faire réagir le compilateur.
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 76
    Points : 31
    Points
    31
    Par défaut Problème de chargement de la fonction somme dans une DLL créée dynamiquement
    Citation Envoyé par tourlourou Voir le message
    N'y a-t-il pas d'alerte du compilateur sur l'appel à la fonction Somme de la ligne 33 ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Somme( .Value, B.Value)
    NB j'ai ajouté une espace pour améliorer la lisibilité.

    La coquille est soit dans le code, soit dans le copier/coller vers le forum, mais, comme Andnotor, je pense qu'elle est susceptible de faire réagir le compilateur.
    puis-je vous demander quelle est votre version de Delphi ?
    Parce que, reconnaissez qu'il y a entre mon code et la version utilisée
    des soucis de compatibilités que je ne maîtrise pas complètement.
    Dans mon premier message
    j'ai fait savoir
    que le programme se compile
    mais c'est en sortie que ça pêche.

    Pourriez-vous, je vous prie,
    me faire quelques suggestions quant à la ligne 33
    puisqu'au moins deux personnes en font allusion ?
    Faut-il rentrer des valeurs numériques ?
    je ne sais plus quoi faire !
    J'ai solutionné les autres problèmes relevés par Andnotor
    mais cette ligne 33 va me faire devenir fou.
    Qu'appelez-vous une coquille en langage clair ?
    Vous voudrez bien considérer que je suis un débutant et que je ne maîtrise pas tout,
    j'ai du boulot dans ce domaine.
    Merci
    Version Delphi utilisé : Rad Studio Alexandria.

  10. #10
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      ShowMessageFmt('%d + %d = %d', [A.Value, B.Value, Somme(????.Value, B.Value)]);
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  11. #11
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Citation Envoyé par Monromero1 Voir le message
    puis-je vous demander quelle est votre version de Delphi ?
    Je retourne la question, prenez l'habitude de l'indiquer lors de la création de chaque nouvelle discussion pour éviter que l'on ait besoin de faire des recherches dans vos autres posts.

    Idem évitez les citations inutiles, encombrant inutilement la lecture. Tant qu'on y est je n'aime pas trop tout ces retours à la ligne découpant vos phrases.

    Je sais, cela ne fait pas avancer (mais la réponse de Paul me semble explicite).

    En fait je suis même étonné que vous utilisiez des .Value , j'aurais simplement écrit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ShowMessageFmt('%d + %d = %d', [A, B, Somme(A, B)]);
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  12. #12
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 76
    Points : 31
    Points
    31
    Par défaut Problème de chargement de la fonction somme dans la DLL
    Bonjour,

    merci pour votre contribution à la solution de mon problème de chargement de la fonction somme.
    A la suite de vos remarques j'ai modifier mon profil dans lequel on pourra trouver ma version de Delphi utilisée,
    et je m'engage à faire des postes plus clairs avec des retours à la ligne intempestifs qui ne figurerons plus dans mes postes.
    et pour finir, je vais mettre la discussion résolue puisque mon problème est solutionné.
    merci encore
    Version Delphi utilisé : Rad Studio Alexandria.

  13. #13
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    Citation Envoyé par Monromero1 Voir le message
    pour finir, je vais mettre la discussion résolue puisque mon problème est solutionné.
    Ben, ce n'est toujours pas fait, pourtant le bouton se trouve juste au dessous du dernier post

    mon profil dans lequel on pourra trouver ma version de Delphi utilisée,
    très bonne idée. Il faut cependant rappeler aux débutants sur le forum que cette signature ne peut être mise en place qu'au bout d'un certain nombre de points (24 à ma souvenance), donc indiquer la version en ouverture de discussion est loin d'être non nécessaire, de plus quand on fait, comme moi de grands écarts entre Delphi 3 et Delphi 11 (Alexandria) c'est loin d'être une option
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 76
    Points : 31
    Points
    31
    Par défaut
    Bonjour,

    Delphi utilisé Rad Studio 11 Alexandria
    En me relisant en profondeur, j'ai tester le bout de code à la ligne 33
    selon vous, m'avez suggéré de remplacer .value par la valeur (A, au lieu de A.value mais cela ne fonctionne toujours pas.
    ShowMessageFmt('%d + %d = %d', [A, B, Somme(A, B)]);
    le compilateur indique :
    valeur (A) non déclarée
    impossible de compiler le programme.
    Vous comprendrez aisément, que je ne peux pas mettre résolu sur une réponse qui ne résout pas
    un problème, un peu de bon sens tout de même !

    Au grand risque de vous faire bondir, j'ai reçu une proposition qui conserve le .value
    ShowMessageFmt('%d + %d = %d', [A.Value, B.Value, Somme(.Value, B.Value)]);
    vous comprendrez que ce code ne fonctionne pas non plus
    car la valeur n'est pas précisée
    alors quoi faire ?
    en conséquence, je reste bloqué avec le même problème qu'à l'origine et voilà tout.
    Je poursuis donc mes recherches en attendant la suggestion providentielle.
    merci pour vos critiques que je convertis en positif
    pour pouvoir avancer.
    Version Delphi utilisé : Rad Studio Alexandria.

  15. #15
    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
    Savez vous que un singe qui tape au hasard sur le clavier d’une machine à écrire, pourra presque sûrement produire un exemplaire d’une pièce de théâtre de Shakespeare ?

    en programmation, c'est pareil, on peut taper au hasard ou réfléchir à ce qu'on fait...une des deux méthodes est plus rapide que l'autre
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  16. #16
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 76
    Points : 31
    Points
    31
    Par défaut
    Pardonnez-moi mais je vous demande :
    en quoi poser une question qui plus ait sur un forum prévu à cet effet est un délis selon vous ?
    Je vous informe qu'en début de discussion j'ai prévenu que je suis débutant en programmation.

    en conséquence,
    je n'apprécie guère vos comparaisons bien inutiles et non fructueuses.
    je ne me compare pas du tout à un singe, je m'informe afin d'en savoir plus et de progresser.
    Et sachez aussi que j'applique le proverbe ou dicton populaire chez nous, "les conseilleurs ne sont pas toujours les payeurs"
    à bonne entendeur salut.
    Surtout quand la critique ne fait l'objet d'aucune forme de proposition.
    où si c'est seulement pour me renvoyer le code incriminé à l'identique.
    J'aurai pu penser librement que c'était une façon bien fine de méprisé le poster que je suis.
    pourtant, moi, j'ai continué d'avancer, mais à présent, la provocation devient insupportable.
    Je vous invite à méditer sur mes propos.
    Je trouve regrettable de nous chicorer sur un forum aux belles intentions.
    Mais je pense aussi que le droit à être un débutant est un droit absolu et méritant.
    En conséquence, je poursuis mes recherches, ne vous en déplaise.
    et j'attends seulement une bonne et vraie proposition qui, elle, me fera avancer.
    Version Delphi utilisé : Rad Studio Alexandria.

  17. #17
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Quelle est l'erreur ?
    Au départ, cela concernait une DLL et des erreurs de type, nous ignorons le problème réel rencontré.

    Commencer par refactorer votre code, mieux isoler la partie DLL dans une classe qui gère tout (Load, Get, Proc(), Free) pour que l'appel soit le plus simple posible
    un code syntaxiquement incorrect puisque compiler peut-être que sur Delphi 11 à cause de nouveauté ?
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  18. #18
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 857
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 857
    Points : 11 291
    Points
    11 291
    Billets dans le blog
    6
    Par défaut
    Bonsoir,

    Certaines réponses ne fournissent pas de solution mais des pistes pour comprendre par soi-même et progresser.

    Tous ont été débutants et utiliser de bonnes méthodes de résolution des problèmes s'acquiert aussi en se posant les bonnes questions : bien exposer un problème est déjà commencer à le résoudre, quand la lumière n'en jaillit pas directement.

    L'aide qu'on trouve ici (ou peut trouver ici, puisqu'elle ne dépend que de la bonne volonté des contributeurs bénévoles) est souvent progressive : une première piste, des précisions demandées, puis de nouvelles pistes, parfois une solution clef en main, mais surtout un guidage.

    Quand vous nous dites que le code compile avec ce qui paraît à d'autres incongru (j'en fais partie) et devant générer une erreur, ils essayent de vous aiguiller, pas de critiquer pour le plaisir (lequel d'ailleurs pourrait-on bien en retirer ?).

    Je peux admettre que la syntaxe .Value à la place de A.Value compile sous une version que je ne peux tester, si vous me le garantissez. J'aimerais cependant comprendre pourquoi.

    Sinon, le compilateur n'a pas l'air de connaître la variable A dans votre ShowMessage : où est-elle déclarée ? De quel type est-elle ?
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  19. #19
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    on est bien d'accord que c'est dans votre code pour tester la bibliothèque que vous écrivez
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       ShowMessageFmt('%d + %d = %d', [A.Value, B.Value, Somme(.Value, B.Value)]);
    pour avoir un appel à la fonction il faut bien que ces valeurs de variables A et B (ou tout autre nom) soit données quelque part.
    exemple sans appel à dll :
    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
     
    procedure TForm1.btnSommeConstanteClick(Sender: TObject);
    var
      variableA,variableB : integer;
      function somme(A,B : Integer) : integer;
      begin
        result:=a+b;
      end;
     
    begin
      variableA:=10;
      variableB:=20;
      ShowMessageFmt('%d + %d = %d', [variableA, variableB,somme(variableA,variableB)]);
      // pouvait aussi s'écrire or variables
      // ShowMessageFmt('%d + %d = %d', [10,20,10+20]);  
    end;
    vous n'avez juste qu'à adapter en ajoutant l'appel de la fonction dans la dll.
    Bien sûr j'imagine que A et B peuvent provenir de zone de saisie (ici une saisie dans des TEdit)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     A:=StrToIntDef(edita.text,0);
     B:=StrToIntDef(editb.text,0);
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  20. #20
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Il serait intéressant de savoir aussi pourquoi ".Value" pour un Integer, cela n'existe pas jusqu'à présent dans le TIntegerHelper qui contient plus une fonction ToString ou ToBoolean pour assurer facilement des conversions de type.

    ".Value" me ferait penser à un TField.Value, déjà commencer par nous expliquer d'où vient cette propriété "Value"
    Ou alors un TSpinEdit qui permet de saisir un entier et possède une propriété Value, je vais choisir cela

    Ensuite, j'insiste sur le fait de découper le code, je dirais dans deux fichiers différents, rien est plus facile que se tromper dans la portée d'une variable.
    Ainsi que bien nommer ses variables et autres composants.

    Voici un exemple complet

    La fenêtre principale d'un projet :

    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    unit CallDll1_MainForm;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons,
      Vcl.Samples.Spin,
      CallDll1_Wrapper;
     
    type
      TCallDll1MainForm = class(TForm)
        SpinEditA: TSpinEdit;
        SpinEditB: TSpinEdit;
        btnSomme: TButton;
        btnSommeConstante: TButton;
        procedure btnSommeClick(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure btnSommeConstanteClick(Sender: TObject);
      private
        { Déclarations privées }
        FMaDLL: TDLL1;
      public
        { Déclarations publiques }
      end;
     
    var
      CallDll1MainForm: TCallDll1MainForm;
     
    implementation
     
    {$R *.dfm}
     
    procedure TCallDll1MainForm.btnSommeClick(Sender: TObject);
    begin
      // Si l'on a déjà chargé la DLL, on a conservé le contexte d'appel 
      if not Assigned(FMaDLL) then
        FMaDLL := TDLL1.Create('DLL1.dll');
     
      // SpinEditA c'est en réalité Self.SpinEditA, c'est implicite
      // Self est l'instance en cours de TCallDll1MainForm, 
      // Comme TCallDll1MainForm a une pro
      ShowMessageFmt('%d + %d = %d', [SpinEditA.Value, SpinEditB.Value, FMaDLL.Somme(SpinEditA.Value, SpinEditB.Value)]);
    end;
     
    procedure TCallDll1MainForm.btnSommeConstanteClick(Sender: TObject);
    var
      variableA, variableB : Integer;
    begin
      if not Assigned(FMaDLL) then
        FMaDLL := TDLL1.Create('DLL1.dll');
     
      variableA := 10; // SpinEditA.Value;
      variableB := 20; // SpinEditB.Value;
      ShowMessageFmt('%d + %d = %d', [variableA, variableB, FMaDLL.Somme(variableA, variableB)]);
    end;
     
    procedure TCallDll1MainForm.FormDestroy(Sender: TObject);
    begin
      FreeAndNil(FMaDLL);
    end;
     
    end.
    Note que btnSommeClick utilise donc SpinEditA.Value qui est une propriété de TCallDll1MainForm,
    Et pour reprendre l'exemple de SergioMaster avec des variables locales c'est dans btnSommeConstanteClick
    Voilà, tu as plein de choses à voir sur les variables et leur portée sans compter leur cycle de vie mais ça c'est une histoire.

    le contenu du fichier DFM :

    Code DFM : 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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    object CallDll1MainForm: TCallDll1MainForm
      Left = 0
      Top = 0
      BorderStyle = bsDialog
      Caption = 'CallDll1MainForm'
      ClientHeight = 98
      ClientWidth = 152
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'Tahoma'
      Font.Style = []
      OldCreateOrder = False
      OnDestroy = FormDestroy
      DesignSize = (
        152
        98)
      PixelsPerInch = 96
      TextHeight = 13
      object SpinEditA: TSpinEdit
        Left = 8
        Top = 8
        Width = 133
        Height = 22
        Anchors = [akLeft, akTop, akRight]
        MaxValue = 0
        MinValue = 0
        TabOrder = 0
        Value = 0
      end
      object SpinEditB: TSpinEdit
        Left = 8
        Top = 36
        Width = 133
        Height = 22
        Anchors = [akLeft, akTop, akRight]
        MaxValue = 0
        MinValue = 0
        TabOrder = 1
        Value = 0
      end
      object btnSomme: TButton
        Left = 38
        Top = 64
        Width = 75
        Height = 25
        Anchors = [akTop]
        Caption = 'Somme'
        TabOrder = 2
        OnClick = btnSommeClick
      end
      object btnSommeConstante: TButton
        Left = 119
        Top = 64
        Width = 22
        Height = 25
        Anchors = [akTop, akRight]
        Caption = '+'
        TabOrder = 3
        OnClick = btnSommeConstanteClick
      end
    end


    Enfin voici le code d'appel de la DLL bien isolé et comme tu le constates, l'utilisation de l'objet rend tout cela plus transparent, pense quand ta DLL deviendra complexe
    La plus subtile est de gérer la durée de vie de la variable FMaDLL


    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    unit CallDll1_Wrapper;
     
    interface
     
    uses Winapi.Windows;
     
    type
      TDLL1 = class(TObject)
      private
        FHandle: THandle;
        FSommeProc: function(A, B: Integer): Integer; stdcall;
      public
        constructor Create(const ADLLName: string; const ADLLDirectory: string = '');
        destructor Destroy(); override;
     
        function Somme(const Operand1, Operand2: Integer): Integer;
      end;
     
    implementation
     
    uses
      System.SysUtils;
     
    { TDLL1 }
     
    constructor TDLL1.Create(const ADLLName: string; const ADLLDirectory: string = '');
    var
      DLLFullName: string;
    begin
      DLLFullName := ADLLDirectory;
      if ADLLDirectory <> '' then
        DLLFullName := IncludeTrailingPathDelimiter(ADLLDirectory) + ADLLName
      else
        DLLFullName := ADLLName;
     
      // On conserve le Handle durant toute la durée de vie de notre classe
      FHandle := LoadLibrary(PChar(DLLFullName));
      if FHandle = 0 then
        RaiseLastOSError();
    end;
     
    destructor TDLL1.Destroy();
    begin
      if FHandle > 0 then
      begin
        FreeLibrary(FHandle);
        FHandle := 0;
      end;
     
      inherited Destroy();
    end;
     
    function TDLL1.Somme(const Operand1, Operand2: Integer): Integer;
    begin
      Result := 0;
      // Sur plusieurs utilisations successives, on conserve le pointeur sur la fonction dans la DLL
      if not Assigned(FSommeProc) then
        FSommeProc := GetProcAddress(FHandle, 'somme');
     
      if Assigned(FSommeProc) then
        Result := FSommeProc(Operand1, Operand2)
      else
        RaiseLastOSError();
    end;
     
    end.
    J'ai volontairement utilisé Operand1, Operand2 dans un cas et A, B pour différencier tout cela, rien n'est plus confusion que d'utiliser les mêmes noms de variable.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Probléme de chargement d'un fichier DLL dans visual studio
    Par youssef_rjili dans le forum Visual Studio
    Réponses: 10
    Dernier message: 29/09/2011, 17h19
  2. Réponses: 7
    Dernier message: 10/09/2005, 16h49
  3. Problème d'utilisation de fonction dans une popup
    Par Pymm dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 06/09/2005, 15h00
  4. Réponses: 2
    Dernier message: 17/08/2005, 11h20
  5. PB pour Appel fonction dans DLL sur Builder3
    Par Fbartolo dans le forum C++Builder
    Réponses: 15
    Dernier message: 10/03/2005, 12h58

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