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 :

DLL, interface ou classe abstraite


Sujet :

Langage Delphi

  1. #1
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 502
    Points : 3 133
    Points
    3 133
    Par défaut DLL, interface ou classe abstraite
    Bonjour,

    Suite à la lecture d'un article ici et des infos données par Paul, je vois qu'il y a plusieurs manières de faire transiter des TObject entre un exe et une dll.

    Méthode 1: Utiliser des interfaces
    Méthode 2: Utiliser des classes abstraites pour obtenir la structure de la classe dans la dll.

    Les deux fonctionnent très bien mais à votre avis, quelle est la meilleure façon de faire ?

    Précision; Dans le cas présent, la dll ne serait utilisée qu'avec un exe produit en Delphi

  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 : 55
    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 457
    Points
    28 457
    Par défaut
    les Interfaces...les classes abstraites sont techniquement la même chose, mais avec une interface tu ne peux pas te tromper, il est impossible d'y mettre quelque chose qui ne soit pas abstrait

  3. #3
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 710
    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 710
    Points : 25 593
    Points
    25 593
    Par défaut
    Cela dépend du contexte
    Si tu compiles avec des BPL de RunTime partagés par Exe et DLL, tu peux échanger des objets directement, ajoute en plus FastShareMem/SimpleShareMem et plus de problème de libération du "mauvais" côté

    Pour ma part, j'utilise des type Interface avec GUID pour gérer la fonction Supports car mes DLL peuvent se comporter comme des Plugins ou Drivers, elles peuvent être "incomplètes" sans que cela impact l'utilisation, l'application affiche que ce qui est supporté (encapsulation de différentes matériels ne proposant pas les mêmes fonctionnalités)
    Et pour les chaines, du BSTR (WideString) ...
    J'étais en C++Builder XE3 quand j'ai poussé à l'extrême l'utilisation de DLL via des Interfaces, il lui fallait encore une DLL pour fonctionner correctement en mode BPL\ShareMem ... ah oui, les projets étaient en RTL dynamique, fallait donc cc3290.dll (les vieux projets c'était CC3260MT.dll) ... j'avais poussé le vice à faire de la délégation d'implémentation d'interface, une DLL pouvait utiliser une autre DLL pour fournir l'implémentation réelle, par exemple, une Caméra en IP c'était la DLL qui implémentait alors qu'une Camera sur DVR, la DLL Caméra était un proxy qui déléguait l'implémentation à la DLL DVR (différentes selon la marques de l'appareil, chacune son protocole comme Dahua ou Panasonic)


    Sinon en Delphi, tu peux maintenant échanger des classes directement, je n'ai pas de code sous la main aujourd'hui mais une collègue l'avait fait à titre expérimentale, j'avoue je me souviens plus de la particularité, je ne crois pas qu'elle la classe était abstraite.

  4. #4
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 502
    Points : 3 133
    Points
    3 133
    Par défaut
    Les interfaces me semblaient aussi plus appropriées maintenant que j'ai pigé le principe (merci Paul)

    Je crains juste les problèmes de portée de mes variables dans le code. Principalement suite à un essai que je viens de faire. Je m'explique.
    Merci de ne pas tacler la qualité du code, ce ne sont que des tests.

    Dans la DDL:
    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
     
    unit UProfile;
     
    interface
     
    uses System.SysUtils, System.Classes, System.StrUtils, System.WideStrUtils;
     
    type
     
      IAdresse = Interface
        function GetRue: string;
        procedure SetRue(Rue: string);
      End;
     
      IProfile = Interface
        ['{AE9B9FC0-27B7-42A3-8F9D-5EFA27482630}']
        function GetNom: string;
        procedure SetNom(Nom: string);
        function GetAdresse: IAdresse;
      End;
     
     
      TAdresse = class(TInterfacedObject, IAdresse)
      private
        FRue: string;
      public
        function GetRue: string;
        procedure SetRue(Rue: string);
      End;
     
      TProfile = class(TInterfacedObject, IProfile)
      private
        FNom    : string;
        FAdresse: TAdresse;
      public
        constructor Create;
        function GetNom: string;
        procedure SetNom(Nom: string);
        function GetAdresse: IAdresse;
      end;
     
    function GetProfile: IProfile; stdcall; export;
     
    implementation
     
    function GetProfile: IProfile; stdcall; export;
    begin
      Result := TProfile.Create;
    end;
     
    { TProfile }
     
    constructor TProfile.Create;
    begin
      inherited;
      FAdresse := TAdresse.Create;
    end;
     
    function TProfile.GetAdresse: IAdresse;
    begin
      Result := FAdresse;
    end;
     
    function TProfile.GetNom: string;
    begin
      Exit(FNom);
    end;
     
    procedure TProfile.SetNom(Nom: string);
    begin
      FNom := Nom;
    end;
     
    { TAdresse }
     
    function TAdresse.GetRue: string;
    begin
      Result := FRue;
    end;
     
    procedure TAdresse.SetRue(Rue: string);
    begin
      FRue := Rue;
    end;
     
    end.
    Dans le programme
    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
     
    ...
     
      IAdresse = Interface
        function GetRue: string;
        procedure SetRue(Rue: string);
      End;
     
      IProfile = Interface
        ['{AE9B9FC0-27B7-42A3-8F9D-5EFA27482630}']
        function GetNom: string;
        procedure SetNom(Nom: string);
        function GetAdresse: IAdresse;
      End;
     
      TFormMain = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
      private
        ProfileTest: IProfile;
      public
      end;
     
    ...
     
    procedure TFormMain.FormCreate(Sender: TObject);
    begin
      ProfileTest := NouveauProfil;
      ProfileTest.SetNom('JLM');
      ProfileTest.GetAdresse.SetRue('rue schuman');
      ShowMessage(ProfileTest.GetNom);
      ShowMessage(ProfileTest.GetAdresse.GetRue);
    end;
     
    procedure TFormMain.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      ShowMessage(ProfileTest.GetNom);
      ShowMessage(ProfileTest.GetAdresse.GetRue);
    end;
    Dans le OnCreate, le nom du profil et l'adresse s'affichent bien.
    [Window Title]
    Testdroits

    [Content]
    JLM

    [OK]
    [Window Title]
    Testdroits

    [Content]
    rue schuman

    [OK]
    Dans le OnClose, j'ai bien le nom mais une chaîne vide pour l'adresse.

    [Window Title]
    Testdroits

    [OK]
    Il y a forcément un truc que je perds en cours de route mais je ne vois pas quoi à part un problème de libération inattendue.

  5. #5
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 502
    Points : 3 133
    Points
    3 133
    Par défaut
    argh, j'ai trouvé. Ma variable "private" FAdresse doit être une interface.
    Maintenant, ça fonctionne.

    Conclusion, les interfaces conviendront très bien.

    Par contre, petite question : Est-ce que vous utilisez des "property" dans vos interfaces en Delphi ?
    Vu que l'on ne peut pas cacher les méthodes d'accès dans une section private, je n'en vois pas l'utilité.
    Ou alors, il y a un moyen que je n'ai pas vu ???

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 710
    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 710
    Points : 25 593
    Points
    25 593
    Par défaut
    Oui, si tu veux garder tes objets en vie, faut les conserver variable Interface pour faire monter le compteur de référence.
    Tu peux aussi faire des weak référence volontairement dans le cas où les deux implémentations s'utilisent mutuellement.

    Fait une unité commune qui ne contient QUE les interfaces partagées par l'appelant et l'implémentation.

    et puis des string échangées, tu peux dire merci à SimpleShareMem


    property oui faut faire le Get voire Set pour Adresse et Nom, ça simplifie juste l'utilisation de la propriété au lieu de accesseurs.

  7. #7
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 502
    Points : 3 133
    Points
    3 133
    Par défaut
    L'unité commune, j'y ai pensé tout à l'heure :-)

    Pour la property, c'est donne l'avantage d'utiliser toujours le même chose pour atteindre les accesseurs, c'est plus propre. Mais rien n’empêche d'utiliser les accesseurs quand même.

    Merci pour vos conseils, je vais pouvoir démarrer quelque chose de concret.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 21/05/2010, 11h46
  2. différence entre interface et classe abstraite
    Par yacin87 dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 29/03/2010, 12h36
  3. Interface ou classe abstraite ?
    Par cobolfingaz dans le forum C#
    Réponses: 6
    Dernier message: 15/07/2008, 18h21
  4. [POO] Différence entre Interface et classe Abstraite
    Par viviboss dans le forum Langage
    Réponses: 7
    Dernier message: 29/11/2006, 17h39
  5. Interface ou classe abstraite ?
    Par Premium dans le forum Langage
    Réponses: 8
    Dernier message: 21/02/2006, 11h23

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