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 :

Passage d'objet en paramètre de DLL


Sujet :

Langage Delphi

  1. #1
    Membre habitué

    Profil pro
    Inscrit en
    Février 2005
    Messages
    317
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 317
    Points : 183
    Points
    183
    Par défaut Passage d'objet en paramètre de DLL
    Bonjour, j'éssaie de programmer une application modulaire. Pour cela, j'ai définit une classe contenant des informations à passer en paramètres à la DLL. Dans ces informations, j'ai une base de données TJvUIBDatabase. Lorsque je regarde avec le déboggueur le numero dans mon application principale et ma DLL j'ai bien la même chose.($2356540). Il me semble que delphi utilise des pointeurs pour les objets non? Bref mon problème est que dans ma DLL, la base n'est pas connectée, et que si je regarde avec le deboggeur, la propriété databasename est nulle ( '' ). Je pensais qu'il pouvait s'agir d'un problème au niveau des champs string de cette classe. Bref, dois-je utiliser un pointer sur un type TJvUIBDatabase et le passer en paramètre? Dois-je utiliser un paquet d'execution?

    Merci d'avance !

  2. #2
    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
    c'est expliqué de multiples fois, Delphi ne permet pas de partager des objets entre EXE et DLL, les paquets sont faits pour ça.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Salut Paul
    Citation Envoyé par Paul TOTH
    c'est expliqué de multiples fois, Delphi ne permet pas de partager des objets entre EXE et DLL, les paquets sont faits pour ça.
    De mon coté, j'ai bien réussi à passer une classe (dérivée de TComponent) vers une DLL. La DLL modifiait le contenu et je n'ai jamais eu de problème notable. Si l'on passe un pointeur, ça marche non?
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  4. #4
    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 Pedro
    Salut Paul

    De mon coté, j'ai bien réussi à passer une classe (dérivée de TComponent) vers une DLL. La DLL modifiait le contenu et je n'ai jamais eu de problème notable. Si l'on passe un pointeur, ça marche non?
    j'ai eu cette conversation y'a 1 mois il me semble avec Troll...on peut faire des tas de choses entre un EXE et une DLL, même avec des objets, mais faut savoir ce qu'on fait parce que c'est pas fait pour
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  5. #5
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par Paul TOTH
    j'ai eu cette conversation y'a 1 mois il me semble avec Troll...on peut faire des tas de choses entre un EXE et une DLL, même avec des objets, mais faut savoir ce qu'on fait parce que c'est pas fait pour
    C'est vrai. Ca reste "limité".
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  6. #6
    Membre habitué

    Profil pro
    Inscrit en
    Février 2005
    Messages
    317
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 317
    Points : 183
    Points
    183
    Par défaut
    Merci de vos réponses, j'éssaie demain avec un pointeur sinon je vais me mettre aux packages

  7. #7
    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 : 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 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Tout à fait Paul TOTH, on a eu un excellent échange à ce sujet, qui a remis au clair, beaucoup de chose à ce sujet

    Nek_kro_kvlt, consulte CE SUJET
    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

  8. #8
    Membre habitué

    Profil pro
    Inscrit en
    Février 2005
    Messages
    317
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 317
    Points : 183
    Points
    183
    Par défaut
    Bon j'ai essayé avec un pointeur déclaré comme 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
     
    type
      PTJvUIBDatabase = ^TJvUIBDatabase;
      PTJvUIBTransaction=^TJvUIBTransaction;
     
    type CModuleInitInfos=record
         parent:TWinControl;
         //DLLName:shortString;
         UIBDatabase:PTJvUIBDatabase;
         UIBTransaction:PTJvUIBTransaction;
         fieldsyears:PChar;
         fieldsw, fieldswg : array of PChar;   //fields normaux et geo
         segmentation,table,resultat:PChar;
    end;
    Dans ma 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
     
      procedure initModule(infos: CModuleInitInfos);stdcall;
      begin
     
         if Form1 = Nil Then
         Form1 := TForm1.Create(Application);
     
         Form1.ParentWindow := infos.parent.Handle;
         Form1.Top:=0;
         Form1.left:=0;
         Form1.Width:=infos.parent.Width;
         Form1.Height:=infos.parent.Height;
         Form1.Show;
         Form1.minfos:=infos;
         Form1.UIBDatabase:=Form1.minfos.UIBDatabase^;
         Form1.dsRes.Database:=infos.UIBDatabase^;
         Form1.dsRes.Transaction:=infos.UIBTransaction^;
     
      end;
     
      procedure updateModule(infos: CModuleInitInfos);stdcall;
      begin
     
         Form1.minfos:=infos;
         Form1.UIBDatabase:=Form1.minfos.UIBDatabase^;
         Form1.afficherres();
      end;
    et dans mon application
    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
     
    procedure TfrmMain.updateModulesInfos();
    var
    i:integer;
    begin
     
    infos.parent:=pnlModule;
     
    infos.UIBDatabase:=@UIBDatabase;
    infos.UIBTransaction:=@UIBTransaction;
     
    infos.fieldsyears:=PChar(fieldsyears);
     
    setlength(infos.fieldsw,length(fieldsw));
    setlength(infos.fieldswG,length(fieldswG));
     
    for i := 0 to length(fieldsw) - 1 do
        infos.fieldsw[i]:=PChar(fieldsw[i]);
     
    for i := 0 to length(fieldswG) - 1 do
        infos.fieldswG[i]:=PChar(fieldswG[i]);
     
    infos.segmentation:=PChar(cmbsegmentation.Text);
    infos.table:=PChar(cmbtables.text);
    infos.resultat:=PChar(cmbresultat.text); {}
     
    if assigned(curmod) then curmod.updateInfos(infos);
    for i := 0 to length(resmods) - 1 do
      resmods[i].updateInfos(infos);
    end;
    Petite précision, j'ai une classe 'module' contenant les accès à mon 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
     
    type CModule=class
      public
      mDLLName:shortString;
      loaded:boolean;
      constructor create(infos: CModuleInitInfos;DLLName:PChar);
      destructor destroy;
      procedure loadDLL(name:string);
      procedure modInit();
      function modInfos():CModuleInfos;
      procedure modUnload();
      procedure updateInfos(infos: CModuleInitInfos);
     
      private
      myHandle:THandle;
      minfos:CModuleInitInfos;
      getModuleInfos : function(): CModuleInfos; stdcall;
      initModule:procedure(infos: CModuleInitInfos);stdcall;
      updateModule:procedure(infos: CModuleInitInfos);stdcall;
      unloadModule:procedure();stdcall;
    end;
    dans ma dll, j'appelle ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
          Form1.UIBDatabase:=Form1.minfos.UIBDatabase^;
         if(minfos.UIBDatabase^.Connected) then showmessage('connected') else showmessage('not connected ' + minfos.uibDatabase^.DatabaseName);
    et j'obtiens 'not connected' et le databasename est vide, alors que dans mon application la base est bien connectée...

    Bref, ai-je oublié quelque chose ?
    je vais essayer avec les package mais bon...
    Dans mon dll j'ai fait ceci:

  9. #9
    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
    à part démontrer que tu ne sais pas à quoi servent les pointeurs...quel est le but recherché par ce code ?

    si tu ne veux pas utiliser de paquets, tu peux utiliser des Interfaces qui sont parfaitement adaptées pour les échanges EXE/DLL.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  10. #10
    Membre habitué

    Profil pro
    Inscrit en
    Février 2005
    Messages
    317
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 317
    Points : 183
    Points
    183
    Par défaut
    Je pensais qu'en passant un pointeur en paramètre je pourrais accéder aux objets de l'application. Bref, as tu un tutorial sur les interfaces? Je connais pas trop les subtilités du language

  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 nek_kro_kvlt
    Je pensais qu'en passant un pointeur en paramètre je pourrais accéder aux objets de l'application. Bref, as tu un tutorial sur les interfaces? Je connais pas trop les subtilités du language
    les interfaces c'est très simple...au départ

    tu veux passer à ta DLL (ou ton EXE, c'est selon) un objet...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    type
     TMonObjet=class
      private
      fData:integer;
     public
      property Data:integer read fData write fData;
     end;
    sauf que ça marche pas...alors il suffit de lui passer une Interface

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    type
     IMonObjet=interface
      function GetData:integer;
      procedure SetData(Value:integer);
      property Data:integer read GetData write SetData;
     end;
    on constate tout de suite une grosse différence entre les deux
    1) l'interface ne possède pas de champ (variable)
    2) elle n'est pas implémentée

    du coup, il manque quelque chose, comme donc va-t-on pouvoir travailler avec ça ?

    et bien du côté DLL (ou EXE c'est selon), il suffit de manipuler les membres, rien d'extraordinaire

    du côté exe, il va falloir produire un objet qui se glisse dans le moule de l'interface

    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
     
     TMonObjet=class(TObject, IMonObjet)
      private
      fData:integer;
      public
      function GetData:integer;
      procedure SetData(Value:integer);
     end;
     
    function TMonObjet.GetData:integer;
    begin
     Result:=fData;
    end;
     
    procedure SetData(Value:integer);
    begin
     fData:=Value;
    end;
    trop simple ! ben oui, sauf qu'il manque IUnknow dont hérite toutes les interfaces, il faut donc ajouter les méthodes AddRef et Release.

    précisons aussi, que Delphi invoque AUTOMATIQUEMENT AddRef et Release quand il manipule une interface...exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    var
     o:TMonObjet;
     i:IMonObjet;
    begin
     o:=TMonObjet.Create;
     i:=o; // appel de i.AddRef;
     i:=nil; // appel de i.Release;
    end;
    selon le code de AddRef/Release, cela peut avoir des conséquences...par exemple TInterfaceObjet s'autodétruit quand il n'est plus référencé (RefCount+1 sur AddRef, RefCount-1 sur Release, Free sur RefCount=0)

    du coup, si TMonObjet dérive de TInterfaceObject et qu'on ajoute un o.Free dans le code ci-dessus, on se chope une exception car o est déjà détruit.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  12. #12
    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
    Si mon souvenir est bon, dans le chapitre 19 de mon livre, y'a un exemple d'utilisation avec un système de plugins. Et ce chapitre est téléchargeable en PDF chez Eyrolle
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  13. #13
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    La notion d'interface n'a rien à voir avec le langage, me semble-t-il.

  14. #14
    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 CapJack
    La notion d'interface n'a rien à voir avec le langage, me semble-t-il.
    voici une réflexion dont la profondeur m'échappe...

    les Interfaces sont utilisées dans tout ce qui est COM, et sous Delphi le mot clé Interface permet de les manipuler plus aisément que ça ne l'était sous Delphi 2 où il fallait déclarer des classes avec des méthodes virtuelles abstraites...voir des records, puisqu'on peut toujours descendre plus bas dans la structure des choses

    donc en un sens la notion d'interface n'est pas liée à Delphi (ce qui permet d'ailleurs de manipuler les objets interfacés de Delphi depuis n'importe quel autre langage supportant les interfaces), mais inversement, les interfaces sous Delphi ne sont pas forcément liées aux objets COM.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  15. #15
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    Ce que je voulais exprimer, mais peut-être me trompé-je, c'est que l'idée d'interface, d'un point de vue théorique, consiste à séparer la partie déclarative d'un objet (moi, objet, qui suis-je, où vais-je, dans quel état j'erre ?), de son implémentation concrète (moi, je Intel x386, exécuter méthode nummer drei, ja !).

    Et ça, c'est surtout fait pour rendre les objets "baladeurs", ce qui inclut les transferts inter-processus certes, mais je pense modestement que ce serait très réducteur de ne voir que celà : c'est aussi une méthode simple pour faire voyager un objet sur un réseau (persistance ?), ou pour pouvoir le faire vivre sur des systèmes différents (portabilité).

    Je suis d'accord avec toi, sauf qu'il n'y a pas que COM et Delphi, même dans le monde merveilleux de l'informatique... j'aurais pu aller plus loin dans ma réflexion effectivement profonde en précisant que l'idée d'interface n'est pas dépendante du langage, ni du système d'exploitation, ni même d'un système particulier tout court. Il me semble, mais ma médiocre intelligence trompe sans doute le vermisseau que je suis, que dans le langage Ada, par exemple, la notion d'interface fait partie intégrante de la sémantique. Autre exemple, le Java, lui, est aussi articulé autour de la notion d'interface pour des raisons de persistance.

    Mais ça ne rendra pas service à notre ami qui a soumis sa question, et à qui je donne une autre piste : et utiliser plutôt des .exe que des .dll, avec de l'OLE automation ? Avec les assistants Delphi, ce sera d'une simplicité magique.. en plus, ça peut permettre de déboguer chaque module séparément de l'application principale, avant d'effectuer le branchement. Juste une idée comme ça.

  16. #16
    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
    je ne suis ni pour ni contre ton explication, bien au contraire

    mais j'ai une approche très pragmatique de l'informatique...et ça m'a plutôt bien réussit jusqu'à présent

    donc pour moi personnellement, une interface n'est rien d'autre qu'un tableau de méthodes, et une méthode n'est rien d'autre qu'une procédure avec un paramètre implicite sur une instance d'objet...au final, un pointeur.

    que l'objet invoqué par cette interface puisse être sur un ordinateur distant dans une autre galaxie, je suis d'accord, mais au niveau de mon programme, j'ai juste un tableau de pointeurs dont le boulot est justement de faire en sorte que je n'ai pas à me soucier de la nature de l'objet qui se trouve de l'autre côté.

    maintenant, cet outil, je peux aussi l'utiliser dans le contexte plus modeste d'un exe et d'une DLL Delphi s'exécutant sur un même poste de travail, et je peux le faire sans utiliser OLE Automation, justement parce que au final, je ne fais que passer une tableau de pointeurs d'un côté à l'autre, tableau dont je connais les tenants et les aboutissants

    Quand on a compris ça, on peut se dire que c'est peu pratique de devoir connaitre la description de l'objet pour l'utiliser...et là OLE Automation prend tout son sens...mais c'est une étape plus loin que le contexte de départ, et on arrive au chapitre des dispinterfaces
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  17. #17
    Membre habitué

    Profil pro
    Inscrit en
    Février 2005
    Messages
    317
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 317
    Points : 183
    Points
    183
    Par défaut
    Merci de vos réponses, je vais essayer de faire une interface !
    Edit: Si j'ai bien compris, il faut implémenter les méthodes addref et release ?
    Ah puis moi j'initialise mon module avec un RECORD, et non une classe, mais ce record contiens un objet TJvUIBDatabase, dois-je donc tout de même faire une interface de mon record ?

  18. #18
    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 nek_kro_kvlt
    Merci de vos réponses, je vais essayer de faire une interface !
    Edit: Si j'ai bien compris, il faut implémenter les méthodes addref et release ?
    Ah puis moi j'initialise mon module avec un RECORD, et non une classe, mais ce record contiens un objet TJvUIBDatabase, dois-je donc tout de même faire une interface de mon record ?
    pour AddRef et Release, tu ne pourras pas compiler ton objet si elles en sont pas définies de toute façon

    ton Record peut rester un record tant qu'il ne contient pas de String, Tableaux dynamiques ou objets...

    Pour préciser ma penser, voici ce que tu peux faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    type
     IUIDBInterface=class
      // placer ici toutes les méthodes dont la DLL a besoin
     end;
     TInteracedUIDataBase=class(TJvUIDataBase,IUIDBInterface)
     end;
    et tu remplaces ton TJvUIDataBase par un TInterfacedUIDataBase

    si c'est pas possible de remplacer TJvUIDataBase, tu passes par une classe intermédiaire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    type
     TInterfaceUIDataBase=class(TInterfacedObject,IUIDBInterface)
      fDB:TJvUIDataBase;
      constructor Create(ADb:TJvUIDataBase);
      // ajouter les méthodes de l'interface, celles-ci exploiteront fDB
     end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  19. #19
    Membre habitué

    Profil pro
    Inscrit en
    Février 2005
    Messages
    317
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 317
    Points : 183
    Points
    183
    Par défaut
    Arf je comprends pas, j'ai essayé de faire un exemple comme 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
    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
    67
    68
     
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, DB, mydbUnit, FBCustomDataSet, JvUIB, JvComponentBase, StdCtrls;
     
    type CModuleInitInfos=record
         public
         parent:TWinControl;
         //DLLName:shortString;
         UIBDatabase:TJvUIBDatabase;
         UIBTransaction:TJvUIBTransaction;
         fieldsyears:PChar;
         fieldsw: Array of PChar;
         fieldswg : Array of PChar;   //fields normaux et geo
         segmentation:PChar;
         table:PChar; 
         resultat:PChar;
     
    end;
     
    type
      TForm1 = class(TForm)
        JvUIBDataBase1: TJvUIBDataBase;
        Button1: TButton;
        procedure FormCreate(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
     
    var
      Form1: TForm1;
       t:CModuleInitInfos;
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
    myHandle:THandle;
    name:string;
    testproc: procedure(t:CModuleInitInfos);
    begin
       name:=IncludeTrailingPathDelimiter(ExtractFilePath(Application.exename))+'test.dll';
     
       myHandle := LoadLibrary(pAnsiChar(name));
       If myHandle = 0 then
       begin
           showmessage('Can''t load module! '+name);
           exit;
       end;
           testproc:=GetProcAddress(myHandle, pAnsiChar('testproc'));
           t.UIBDatabase:=JvUIBDataBase1;
           testproc(t);
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
        JvUIBDataBase1.Connected:=true;
    end;
     
    end.
    et dans la dll test.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
    37
    38
    39
    40
    41
    42
     
    library test;
     
    { Important note about DLL memory management: ShareMem must be the
      first unit in your library's USES clause AND your project's (select
      Project-View Source) USES clause if your DLL exports any procedures or
      functions that pass strings as parameters or function results. This
      applies to all strings passed to and from your DLL--even those that
      are nested in records and classes. ShareMem is the interface unit to
      the BORLNDMM.DLL shared memory manager, which must be deployed along
      with your DLL. To avoid using BORLNDMM.DLL, pass string information
      using PChar or ShortString parameters. }
     
    uses
      SysUtils,
      Classes,Dialogs, DB, JvUIB, JvComponentBase,windows,Controls ;
     
    {$R *.res}
    type CModuleInitInfos=record
         public
         parent:TWinControl;
         //DLLName:shortString;
         UIBDatabase:TJvUIBDatabase;
         UIBTransaction:TJvUIBTransaction;
         fieldsyears:PChar;
         fieldsw: Array of PChar;
         fieldswg : Array of PChar;   //fields normaux et geo
         segmentation:PChar;
         table:PChar; 
         resultat:PChar;
     
    end;
     
    procedure testproc(t:CModuleInitInfos);
    begin
        showmessage(t.UIBDatabase.DatabaseName);
        if(t.UIBDatabase.Connected) then showmessage('connected');
    end;
     
    exports testproc;
    begin
    end.
    lorsque je cliques sur le bouton dans ma form, j'obtiens le chemin de la base, et je vois marqué connecté... Le problème doit donc venir d'ailleurs, mais je capte pas, car dans mon projet ça ne marches pas:

    je mets au cas ou ma source:
    la classe qui charge le 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
    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
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
     
    unit modsCls;
     
    interface
    Uses sysutils, classes, windows,dialogs,controls,jvuib,jvuiblib;
    type CModuleInfos=record
       description,name:PChar;
    end;
     
     
    type CModuleInitInfos=record
         public
         parent:TWinControl;
         //DLLName:shortString;
         UIBDatabase:TJvUIBDatabase;
         UIBTransaction:TJvUIBTransaction;
         fieldsyears:PChar;
         fieldsw: Array of PChar;
         fieldswg : Array of PChar;   //fields normaux et geo
         segmentation:PChar;
         table:PChar; 
         resultat:PChar;
     
    end;
     
     
    type CModule=class
      public
      mDLLName:shortString;
      loaded:boolean;
      constructor create(infos: CModuleInitInfos;DLLName:PChar);
      destructor destroy;
      procedure loadDLL(name:string);
      procedure modInit();
      function modInfos():CModuleInfos;
      procedure modUnload();
      procedure updateInfos(infos: CModuleInitInfos);
     
      private
      myHandle:THandle;
      minfos:CModuleInitInfos;
      getModuleInfos : function(): CModuleInfos; stdcall;
      initModule:procedure(infos: CModuleInitInfos);stdcall;
      updateModule:procedure(infos: CModuleInitInfos);stdcall;
      unloadModule:procedure();stdcall;
    end;
     
    implementation
     
     
    constructor CModule.create(infos: CModuleInitInfos;DLLName:PChar);
    begin
         myHandle:=0;
         minfos:=infos;
         mDLLName:=DLLName;
         loaded:=false;
         loadDLL(mDLLName);
    end;
    procedure CModule.modInit();
    begin
        initModule(minfos);
        loaded:=true;
    end;
     
    procedure CModule.modUnload();
    begin
       unloadModule();
       loaded:=false;
    end;
     
    function CModule.modInfos():CModuleInfos;
    begin
       result:=getModuleInfos();
    end;
     
    procedure CModule.updateInfos(infos: CModuleInitInfos);
    begin
         minfos:=infos;
     
         if not loaded Then  exit;    //on peut mettre à jour avant d'initialiser
     
         updateModule(infos);
    end;
    destructor CModule.destroy();
    begin
         if(loaded) then modUnload();
     
         getModuleInfos:=nil;
         initModule:=nil;
         updateModule:=nil;
         unloadModule:=nil;
         if myHandle<>0 then
            FreeLibrary(myHandle);
    end;
     
     
    procedure CModule.loadDLL(name:string);
    begin
      myHandle := LoadLibrary(pAnsiChar(name));
       If myHandle = 0 then
       begin
           showmessage('Can''t load module! '+name);
           exit;
       end;
           getModuleInfos:=GetProcAddress(myHandle, pAnsiChar('getModuleInfos'));
           initModule:=GetProcAddress(myHandle, pAnsiChar('initModule'));
           updateModule:=GetProcAddress(myHandle, pAnsiChar('updateModule'));
           unloadModule:=GetProcAddress(myHandle, pAnsiChar('unloadModule'));
    end;
     
    end.
    le dll, qui contiens une form.
    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
     
      function getModuleInfos(): CModuleInfos; stdcall;
      begin
           result.description:='Ce module permet d''afficher les résultats sous forme brute';
           result.name:=PChar('Résultats bruts');
      end;
     
      procedure initModule(infos: CModuleInitInfos);stdcall;
      begin
     
     
         showmessage(infos.UIBDatabase.DatabaseName);
        if(infos.UIBDatabase.Connected) then showmessage('connected');
     
         if Form1 = Nil Then
         Form1 := TForm1.Create(Application);
     
         Form1.ParentWindow := infos.parent.Handle;
         Form1.Top:=0;
         Form1.left:=0;
         Form1.Width:=infos.parent.Width;
         Form1.Height:=infos.parent.Height;
         Form1.Show;
         Form1.minfos:=infos;
         Form1.UIBDatabase:=Form1.minfos.UIBDatabase;
         Form1.dsRes.Database:=infos.UIBDatabase;
         Form1.dsRes.Transaction:=infos.UIBTransaction;
     
      end;
     
      procedure updateModule(infos: CModuleInitInfos);stdcall;
      begin
     
         Form1.minfos:=infos;
         Form1.UIBDatabase:=Form1.minfos.UIBDatabase;
         Form1.afficherres();
      end;
        procedure unloadModule();stdcall ;
        begin
             form1.Destroy;
        end;
    exports
        initModule,getModuleInfos,updateModule,unloadModule;
    et le chargement dans l'application:
    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
     
      resmods: array of CModule;
      curmod:CModule;   //current module
      infos: CModuleInitInfos;
    //....
    procedure TfrmMain.updateModulesInfos();
    var
    i:integer;
    begin
     
     
     
    infos.UIBDatabase:=UIBDatabase;
     
    {
    infos.parent:=pnlModule;
    infos.UIBTransaction:=UIBTransaction;
     
    infos.fieldsyears:=PChar(fieldsyears);
     
    setlength(infos.fieldsw,length(fieldsw));
    setlength(infos.fieldswG,length(fieldswG));
     
    for i := 0 to length(fieldsw) - 1 do
        infos.fieldsw[i]:=PChar(fieldsw[i]);
     
    for i := 0 to length(fieldswG) - 1 do
        infos.fieldswG[i]:=PChar(fieldswG[i]);
     
    infos.segmentation:=PChar(cmbsegmentation.Text);
    infos.table:=PChar(cmbtables.text);
    infos.resultat:=PChar(cmbresultat.text); }
     
    if assigned(curmod) then curmod.updateInfos(infos);
    for i := 0 to length(resmods) - 1 do
      resmods[i].updateInfos(infos);
    end;
    //......
    updateModulesInfos();  
    curmod.modInit;
    Je suis désolé de balancer autant de code, mais j'ai l'impression que si ça marche dans mon test, ça devrais marcher dans mon application, je dois oublier quelque chose mais je ne vois pas quoi !! La seule différence aurait été que je rempli les autres variable de mon objet CModuleInfos mais je les ai commentés :s

    Merci en tous cas de tes réponses paul.

  20. #20
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Points : 754
    Points
    754
    Par défaut
    Bonjour,

    Je n'ai pas vraiment suivi la discussion mais voici le lien du site de Zarko Gajic
    http://delphi.about.com/od/beginners/l/aa113004a.htm qui présente un très bon tuto sur les Interfaces.


    @+

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

Discussions similaires

  1. [POO] Passage d'objet en paramètre
    Par tintin72 dans le forum Langage
    Réponses: 6
    Dernier message: 13/08/2008, 20h06
  2. Passage d'Objet en paramètre d'un formulaire
    Par wadoo dans le forum IHM
    Réponses: 9
    Dernier message: 03/07/2008, 09h54
  3. passage d'objet en paramètre
    Par chilokan dans le forum Delphi
    Réponses: 6
    Dernier message: 07/05/2007, 21h29
  4. [WD10]Passage d'objet en paramètres de methode
    Par Isildur dans le forum WinDev
    Réponses: 25
    Dernier message: 26/03/2007, 17h35
  5. [DLL] Passage d'objet en paramètre
    Par TitiFr dans le forum Langage
    Réponses: 4
    Dernier message: 20/08/2005, 23h18

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