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 :

Affecter une procédure à un évènement dans une dll


Sujet :

Delphi

  1. #1
    Membre habitué Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2017
    Messages : 260
    Points : 171
    Points
    171
    Par défaut Affecter une procédure à un évènement dans une dll
    Bonjour,

    Comment puis je faire pour affecter ma procedure "MySetText" à l'évènement (MyDataSet.Fields[...].OnSetText) dans ma dll ?

    Exemple :

    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
    library MyDll;
     
    procedure MySetText(Sender: TField; const Text: String);
    begin
       try
          Sender.Value := Text;
       except
        {...}
       end;
    end;
     
    procedure MyAddRecord(MyDataSet: TClientDataSet);
    var
      IField: Integer;
    begin
      for IField := 0 to MyDataSet.IndexDefs.Count - 1 do
      begin
        {...}
        MyDataSet.Fields[IField].OnSetText := MySetText;
        {...}
      end; 
    end;
     
    exports
      MyAddRecord;
     
    end.
    Merci
    Vous ne pouvez pas faire confiance à un code que vous n'avez pas totalement rédigé vous-même.

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 455
    Points : 24 867
    Points
    24 867
    Par défaut
    Tout est dans la DLL ?
    Tu dois faire une classe pour déclarer ton gestionnaire d'évènement procedure TClasse.MySetText(... car un gestionnaire doit une procedure of object;

    Si c'est un EXE, tu dois faire un CallBack, j'ai un exemple avec un Ping qui utilise un Entier pour retrouver un contexte (dans ton cas le Sender ce qui peut être utile)
    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
    Membre habitué Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2017
    Messages : 260
    Points : 171
    Points
    171
    Par défaut
    Bonjour ShaiLeTroll

    Oui tout dans la dll, c'est le première fois que je suis confronté à ce qu'a de figure.

    // 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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    library MyDll;
     
    procedure MySetText(Sender: TField; const Text: String);
    begin
       try
          Sender.Value := Text;
       except
        {...}
       end;
    end;
     
    procedure MyAddRecord(MyDataSet: TClientDataSet);
    var
      IField: Integer;
    begin
      for IField := 0 to MyDataSet.IndexDefs.Count - 1 do
      begin
        {...}    
        MyDataSet.Fields[IField].OnSetText := MySetText;
        {...}
        {Création d'un formulaire dynamique}
      end; 
        {...}
      MyForm.ShowModal;
     
      try
        MyDataSet.Post;
      except
         {...}
      end;
    end;
     
    exports
      MyAddRecord;
     
    end.
    // Form
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     unit MyUnit;
    {...}
    {Déclaration de la procedure à importer}
    procedure MyAddRecord(MyDataSet: TClientDataSet); external MyDll.dll  name 'MyAddRecord'; 
     
    implementation
     
    { Exemple }
    procedure TFMyUnit.ExecuteClick(Sender: TObject);
    begin
       MyAddRecord(ClientDataSet1);
    end;
    Vous ne pouvez pas faire confiance à un code que vous n'avez pas totalement rédigé vous-même.

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 455
    Points : 24 867
    Points
    24 867
    Par défaut
    Si tout est côté DLL c'est tout bête
    Même pas besoin de faire une instance, une méthode de classe suffira

    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
    library MyDll;
     
    type
      TEventHandler = class(TObject)
        class procedure MySetText(Sender: TField; const Text: String);
      end;
     
    class procedure TEventHandler.MySetText(Sender: TField; const Text: String);
    begin
       try
          Sender.Value := Text;
       except
        {...}
       end;
    end;
     
    procedure MyAddRecord(MyDataSet: TClientDataSet);
    var
      IField: Integer;
    begin
      for IField := 0 to MyDataSet.IndexDefs.Count - 1 do
      begin
        {...}    
        MyDataSet.Fields[IField].OnSetText := TEventHandler.MySetText; 
        {...}
        {Création d'un formulaire dynamique}
      end; 
        {...}
      MyForm.ShowModal;
     
      try
        MyDataSet.Post;
      except
         {...}
      end;
    end;
     
    exports
      MyAddRecord;
     
    end.
    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

  5. #5
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    procedure of object possible sur une class procedure ?! J'ai jamais testé, ca peut etre pratique si ca fonctionne
    Je pense que tu t'es trompé dans ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MyDataSet.Fields[IField].OnSetText := TEventHandler.MySetText;

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 455
    Points : 24 867
    Points
    24 867
    Par défaut
    Tout à fait guillemouze, j'ai corrigé, il fallait bien lui mettre la classe
    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

  7. #7
    Membre habitué Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2017
    Messages : 260
    Points : 171
    Points
    171
    Par défaut Métaclasse


    Merci ShaiLeTroll.
    Vous ne pouvez pas faire confiance à un code que vous n'avez pas totalement rédigé vous-même.

  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 445
    Points
    28 445
    Par défaut
    STOP ! ce n'est pas possible de partager des classes objets entre l'exe et la DLL !

    or c'est ce que tu fais ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    {Déclaration de la procedure à importer}
    procedure MyAddRecord(MyDataSet: TClientDataSet); external MyDll.dll  name 'MyAddRecord'; 
     
    implementation
     
    { Exemple }
    procedure TFMyUnit.ExecuteClick(Sender: TObject);
    begin
       MyAddRecord(ClientDataSet1); // passage d'un objet de l'exe vers la DLL
    end;
    le stricte minimum c'est d'avoir ShareMem pour partager le même gestionnaire de mémoire entre les deux sinon toute allocation viendra planter le tout

    mais même avec ShareMem, la DLL et l'EXE possèdent leur propre version de l'objet , ça peut éventuellement fonctionner si l'exe et la dll sont compilés avec le même compilateur mais c'est tellement sensible que je ne m'y risquerait pas.

    c'est la raison pour laquelle les Packages (qui sont des DLL) sont totalement dépendants du compilateur.

    Pour faire les choses proprement il faut passer par des Interfaces, la DLL doit manipuler une classe IDataSet qui possède des IField et l'exe doit fournir des objets qui implémentent ces interfaces on manipulant des TDataSet et TField

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    unit Data.IDataSet;
     
    type
      IField = interface
      ...
      end;
     
      IDataSet = interface
        function GetFieldCount: Integer;
        function GetField(Index: Integer): IField;
      end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    library mydll;
     
    uses
      Data.IDataSet;
     
    procedure MyAddRecord(MyDataSet: IDataSet);
    begin
      ...
    end;
    // exe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    type
      TFieldImpl = class(TInterfacedObject, IField)
       ...
      end;
     
      TDataSetImpl = class(TInterfacedObject, IDataSet)
        FDataSet: TTClientDataSet;
        function GetFieldCount: Integer;
        function GetField(Index: Integer): IField;
      end;
    c'est du boulot, mais ensuite tu peux manipuler tes interfaces en toute liberté y compris avec un autre langage de programmation
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 455
    Points : 24 867
    Points
    24 867
    Par défaut
    Compilé en BPL d'exécution, ShareMem, un EXE peut utiliser des classes d'une DLL, je l'ai fait avec une TSQLConnection partagé entre un EXE et peut-être 20 DLLs
    Idem, une fenêtre de l'EXE affiche une fenêtre de la DLL via imbrication de la propriété Parent, cette dernière pouvant contenir une fenêtre aussi imbriqué par Parent d'une seconde DLL comme des poupées russes.

    Même si j'ai pratiqué énormément les interfaces et je confirme que c'est un gros boulot
    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

  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 445
    Points
    28 445
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Compilé en BPL d'exécution, ShareMem, un EXE peut utiliser des classes d'une DLL, je l'ai fait avec une TSQLConnection partagé entre un EXE et peut-être 20 DLLs
    Idem, une fenêtre de l'EXE affiche une fenêtre de la DLL via imbrication de la propriété Parent, cette dernière pouvant contenir une fenêtre aussi imbriqué par Parent d'une seconde DLL comme des poupées russes.

    Même si j'ai pratiqué énormément les interfaces et je confirme que c'est un gros boulot
    Attention, il y a une marge entre "ça fonctionne" et "c'est la bonne approche"

    je me souviens d'un projet Delphi 5 qui partageait une TStringList avec une DLL Delphi 2005...et "ça fonctionnait" effectivement, mais pour la simple et bonne raison que la DLL créait et chargeait la SL et l'exe se contentait de la lire sans jamais rien modifier..comme TStringList hérite de TStrings avec des méthodes virtuelles partout (qui n'avaient pas évolué entre les deux versions de Delphi); techniquement, on a quasiment une Interface en fait. Si la DLL avait été réalisée sous Delphi 2009 en Unicode ça aurait été totalement incompatible.

    si on veux faire des modules, il faut utiliser des BPL, c'est d'autant plus intéressant que le code est réellement partagé et que la taille des binaires diminues drastiquement, et de plus Delphi se charge de vérifier que les BPL et l'EXE sont bien compatibles. Sinon il faut faire le travail d'abstraction via des Interface ou même une API de type C.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 26/12/2010, 21h20
  2. Réponses: 1
    Dernier message: 03/09/2009, 12h39
  3. Réponses: 3
    Dernier message: 06/09/2006, 09h06
  4. Réponses: 4
    Dernier message: 28/08/2006, 13h04
  5. [c++]Mettre une procédure de fenetre dans une class
    Par Spartan03 dans le forum Windows
    Réponses: 10
    Dernier message: 01/12/2005, 10h56

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