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 :

Comment utiliser une classe d'un paquet chargé dynamiquement ?


Sujet :

Langage Delphi

  1. #1
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    mai 2002
    Messages
    2 614
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Savoie (Rhône Alpes)

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

    Informations forums :
    Inscription : mai 2002
    Messages : 2 614
    Points : 6 147
    Points
    6 147
    Par défaut Comment utiliser une classe d'un paquet chargé dynamiquement ?
    Comment utiliser une classe d'un paquet chargé dynamiquement ?

    Je ne connaissais pas du tout l'utilisation dynamique des paquets.
    J'ai donc regardé ce tutoriel : http://sjrd.developpez.com/delphi/tutoriel/compoplugin/ (Surtout les chapitres I - B, I - C, I - E)

    Comme conseillé dans le chapitre 'I - E', j'ai créé une classe ancêtre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      TClassTestAncetre = class(TComponent)
        public
          procedure Test;   virtual;   abstract;
          function GetDate: String;   virtual;   abstract;
      end;
    Puis, la classe du paquet :
    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
      TClassTest = class(TClassTestAncetre)
        public
          procedure Test;   override;
          function GetDate: String;   override;
      end;
     
    ...
     
    procedure TClassTest.Test;
    begin
      ShowMessage('Test');
    end;
     
    function TClassTest.GetDate: String;
    begin
      Result := FormatDateTime('dd/mm/yyyy', Now);
    end;
     
    ...
     
    initialization
      RegisterClass(TClassTest);
    finalization
      UnregisterClass(TClassTest);
    end.
    Et enfin, mon application faisant appel au paquet :
    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
    procedure TForm1.BtnClasseTestClick(Sender: TObject);
    var
      Module: HMODULE;
      Classe: TPersistentClass;
      Instance: TClassTestAncetre;
    //  Instance: TClassTest;
    begin
      Module := LoadPackage(NOM_PAQUET);
      if Module <> 0 then
      begin
        try
          Classe := GetClass('TClassTest');
          if Assigned(Classe) then
          begin
            if Classe.InheritsFrom(TClassTestAncetre) then
            begin
              Instance := TClassTestAncetre(Classe).Create(nil);          // <<-- Plante ici !
              try
                Instance.Test;
              finally
                Instance.Free;
              end;
            end
            else
              ShowMessage('not Classe.InheritsFrom(TClassTestAncetre) !');
          end
          else
            ShowMessage('not Assigned(Classe) !');
        finally
          UnloadPackage(Module);
        end;
      end;
    end;
    Et j'obtiens une violation d'accès sur la création de l'objet Instance.
    Que ce soit une variable de type TClassTest ou TClassTestAncetre n'y change rien.

    Qu'est ce que j'ai raté ?
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. Écrivez dans un français correct !!

    Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise
    OpenGL 2.1 - Oracle 10g - Interbase (7 - XE) - PostgreSQL 11.6

  2. #2
    Membre expérimenté
    Avatar de retwas
    Homme Profil pro
    Développeur Java/Delphi
    Inscrit en
    mars 2010
    Messages
    698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Java/Delphi
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 698
    Points : 1 608
    Points
    1 608
    Billets dans le blog
    4
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Instance := TClassTestAncetre(Classe.Create);


    Sinon tu peux aussi utiliser la Rtti.

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

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : juillet 2006
    Messages : 12 063
    Points : 21 208
    Points
    21 208
    Par défaut
    Plutôt ceci ?
    le nil obligatoire pour utiliser le constructeur du TComponent qu'hérite le TClassTestAncetre

    En fait, tu transtype une méta classe en référence de classe et appele le constructeur sur une instance qui n'en ait pas une !
    Violation d'accès parce que le Create pointe pas où il faut, en tout cas, pas du code

    Il faut bien transtyper la méta classe TPersistentClass en TComponentClass pour bénéficier du constructeur virtuel du TComponent
    Ensuite transtyper la référence sur un TComponent en une référence sur un TClassTestAncetre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Instance := TClassTestAncetre(TComponentClass(Classe).Create(nil));
    on pourrait aussi écrire (ma préférence car bien lisible et l'on a une méta classe explicite)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TClassTestAncetreClass = class of TClassTestAncetre;
    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
    procedure TForm1.BtnClasseTestClick(Sender: TObject);
    var
      Module: HMODULE;
      Classe: TPersistentClass;
      InstanceClasse: TClassTestAncetreClass;
      Instance: TClassTestAncetre;
     
    begin
      Module := LoadPackage(NOM_PAQUET);
      if Module <> 0 then
      begin
        try
          Classe := GetClass('TClassTest');
          if Assigned(Classe) then
          begin
            if Classe.InheritsFrom(TClassTestAncetre) then
            begin
              InstanceClasse := TClassTestAncetreClass(Classe);
              Instance := InstanceClasse.Create(nil);     
              try
                Instance.Test;
              finally
                Instance.Free;
              end;
            end
            else
              ShowMessage('not Classe.InheritsFrom(TClassTestAncetre) !');
          end
          else
            ShowMessage('not Assigned(Classe) !');
        finally
          UnloadPackage(Module);
        end;
      end;
    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

  4. #4
    Rédacteur/Modérateur
    Avatar de Andnotor
    Profil pro
    Inscrit en
    septembre 2008
    Messages
    5 119
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : septembre 2008
    Messages : 5 119
    Points : 11 217
    Points
    11 217
    Par défaut
    Le transtypage que tu appliques est pour une instance de classe (un objet), pas pour la classe elle-même. Pour cela, il faut une référence de classe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    type
      TClassTestAncetreClass = class of TClassTestAncetre; 
      TClassTestAncetre = class(TComponent)
        ...
      end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Instance := TClassTestAncetreClass(Classe).Create(nil);
    EDIT:
    Shai a tout dit

  5. #5
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    mai 2002
    Messages
    2 614
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Savoie (Rhône Alpes)

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

    Informations forums :
    Inscription : mai 2002
    Messages : 2 614
    Points : 6 147
    Points
    6 147
    Par défaut
    Effectivement, ça marche.
    pour les explications : je pense avoir mieux compris.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. Écrivez dans un français correct !!

    Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise
    OpenGL 2.1 - Oracle 10g - Interbase (7 - XE) - PostgreSQL 11.6

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

Discussions similaires

  1. [1.x] comment utiliser une class métier perso ?
    Par guiyomh dans le forum Symfony
    Réponses: 2
    Dernier message: 19/11/2008, 12h56
  2. Comment utiliser une classe Java dans une appli PB ?
    Par bobychezA56 dans le forum Powerbuilder
    Réponses: 0
    Dernier message: 09/04/2008, 18h07
  3. Réponses: 0
    Dernier message: 31/03/2008, 11h36
  4. Comment utiliser une classe ?
    Par toinou62 dans le forum ASP
    Réponses: 1
    Dernier message: 09/10/2007, 21h39
  5. Réponses: 2
    Dernier message: 05/08/2006, 13h29

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