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 :

Erreur invocation d'un constructeur RTTI


Sujet :

Langage Delphi

  1. #1
    Membre averti Avatar de Moez.B
    Homme Profil pro
    Développeur Delphi
    Inscrit en
    Mars 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Tunisie

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 219
    Points : 370
    Points
    370
    Par défaut Erreur invocation d'un constructeur RTTI
    Bonjour,
    J'ai repris le code basique comme initiation aux RTTI de Robert Love dans son blog et je l'ai adapté à mes connaissance, mais j'ai une erreur de violation d'accès au niveau de la création de la StringList,
    Le code est très simple, il illustre la création dynamique d'une StringList, l'alimenter de quelques lignes et d'afficher son contenu, tout ceci dans une application console, alors je voici le 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
    42
    43
     
    program Project1;
     
    {$APPTYPE CONSOLE}
     
    {$R *.res}
     
    uses
      Vcl.StdCtrls,
      System.Classes,
      System.TypInfo,
      System.Rtti;
     
    Var
      Contexte: TRttiContext;
      MonType: TRttiType;
      TypeInstance: TRttiInstanceType;
      ClasseDeReference: TClass;
      StringList: TValue;
      Lignes: TValue;
    begin
      // Création du contexte
      Contexte := TRttiContext.Create;
      Try
        // Identification du type
        MonType             := Contexte.FindType('Classes.TStringList');
        TypeInstance        := MonType as TRttiInstanceType;
        ClasseDeReference   := TypeInstance.MetaclassType;
     
        // Invocation des méthodes
        // 1. Création de la StringList
        StringList := TypeInstance.GetMethod('Create').Invoke(ClasseDeReference, []).AsType<TStringList>;
        // 2. Ajout d'une ligne à notre StringList
        TypeInstance.GetMethod('Add').Invoke(StringList, ['Bonjour, comment vas tu?']);
        // 3. Ajout d'une seconde ligne à la StringList
        TypeInstance.GetMethod('Add').Invoke(StringList, ['Bon, je dois te laisser maintenant']);
        Lignes := TypeInstance.GetProperty('Text').GetValue(StringList.AsObject);
        WriteLn(Lignes.ToString);
      Finally
        Contexte.Free;
      End;
      Readln;
    end.
    Le compilateur s'arrête à l'invocation de la méthode Create de la StringList, dans le code de Robert, il fait l'appel de Invoke sans le cast AsType<TStringList>, je l'ai ajouté, mais j'ai toujours cette erreur mémoire.


    J'ai essayé pas mal de façons pour invoquer le constructeur mais toujours cette erreur mémoire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        //    1.2 Option #2 j'essaie encore avec le constructeur du contexte RTTI ... ça marche pas !
        StringList := (Contexte.FindType('Classes.TStringList') as TRttiInstanceType).MetaclassType.Create;
        //    1.3 Option #3 une autre façon pour le faire mais ...
        StringList := TClass((Contexte.FindType('Classes.TStringList') as TRttiInstanceType).MetaclassType).Create;
    Au début du code, je me suis dit que peut être if faut inculre les directives pour les RTTI et donc j'ai ajouté les directives suivantes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {$M+} {$TYPEINFO ON} {$METHODINFO ON}
    Comment alors peut-on corriger l'invocation du constructeur de notre StringList,
    Merci d'avance..
    Images attachées Images attachées  

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 736
    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 736
    Points : 25 645
    Points
    25 645
    Par défaut
    Cela semble être les nouvelles RTTI !

    Est-ce que inclu le code de TStringList dans ton projet ?
    Comment se comporte l'optimisation ?
    Si TStringList n'est pas utilisé dans le projet, est-ce son code est compilé quand même ?
    TStringList est une classe package, cela doit aussi changer selon la construction avec ou sans package

    A mon avis Contexte.FindType('Classes.TStringList') renvoie nil car la classe n'est pas compilée dans l'exe

    Est-ce que cette variante fonctionne-t-elle mieux ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonType             := Contexte.GetType(TStringList);


    Pour la directive TYPEINFO, je pense que c'est plus lié au RTTI classique de gestionnaire de flux pour les propriétés et méthodes publiées


    Sinon, tu as des méthodes plus simple pour invoquer un constructeur, quel est ton but ?
    Explorer les RTTI - continue alors
    Faire une Factory couplé à une Class Registry que l'on pourrait assimiler à une Pattern Strategy façon Delphi ou dans l'esprit du Registre des objet COM,
    et dans ce cas, une TClassList ou un array of TClass serait bien plus simple

  3. #3
    Membre averti Avatar de Moez.B
    Homme Profil pro
    Développeur Delphi
    Inscrit en
    Mars 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Tunisie

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 219
    Points : 370
    Points
    370
    Par défaut
    Salut,
    Oui, ce sont les nouvelles RTTI qui ne cessent de changer de version à une autre.
    Est-ce que inclu le code de TStringList dans ton projet ?
    Il n'y a pas un code pour la TStringList, tout est créé en dynamique en appelant les types et les informations alliés à l'exécution.
    Comment se comporte l'optimisation ?
    Béhhh, réellement, je n'ai pas une idée..
    Si TStringList n'est pas utilisé dans le projet, est-ce son code est compilé quand même ?
    Oui, il est complié, l'erreur mémoire est arrivé pendant l'exéction, syntaxiquement, aucune erreur, c'est une erreur de pointeur sur une classe non trouvée normalement...
    TStringList est une classe package, cela doit aussi changer selon la construction avec ou sans package
    A mon avis Contexte.FindType('Classes.TStringList') renvoie nil car la classe n'est pas compilée dans l'exe
    Oui, elle renvoie nil mais en RTTI tous les types sont à nil même dans les quelques petits tests qui ont réussi ... voici un autre petit test:
    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
     
    program Project1;
     
    {$APPTYPE CONSOLE}
     
    {$R *.res}
     
    uses
      Vcl.StdCtrls,
      System.Rtti,
      System.TypInfo;
     
    Var
      Contexte: TRttiContext;
      Methode: TRttiMethod;
    begin
      Contexte := TRttiContext.Create;
      For Methode in Contexte.GetType(TButton).GetMethods do
      Begin
        WriteLn(Methode.ToString);
      End;
      Contexte.Free;
      Readln;
    end.
    et là quand je débuge, Methode est à nil , Contexte.GetType(TButton) est à nil aussi ... mais, dans ce test, ça liste toutes les méthodes de la classe TButton.
    Est-ce que cette variante fonctionne-t-elle mieux ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MonType             := Contexte.GetType(TStringList);
    ça ne marche pas, pour la simple raison qu'on doit passer un pointeur comme paramètre, j'entends parler donc avec ce paramètre ATypeInfo: Pointer, une instance de classe qui est déjà créée et qu'on récupère ses informations ....
    Pour la directive TYPEINFO, je pense que c'est plus lié au RTTI classique de gestionnaire de flux pour les propriétés et méthodes publiées
    Tu as parfaitement raison...
    Sinon, tu as des méthodes plus simple pour invoquer un constructeur, quel est ton but ?
    Explorer les RTTI - continue alors
    : Mon but est d'explorer , je veux simuler l'instanciation d'une TStringList, l'appel à ses méthodes en utilisant les RTTI, travailler aussi avec les attributes Après peut être que je vais travailler sur une partie d'automatisation de traitement déjà existant...
    Faire une Factory couplé à une Class Registry que l'on pourrait assimiler à une Pattern Strategy façon Delphi ou dans l'esprit du Registre des objet COM,
    et dans ce cas, une TClassList ou un array of TClass serait bien plus simple
    Merci pour ton explication, mais est ce que tu peux éclaircir un peu : niveau de compréhension : 0% dans tu ce que tu as mentionné ici
    Merci..

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 736
    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 736
    Points : 25 645
    Points
    25 645
    Par défaut
    Citation Envoyé par Moez.B Voir le message
    Oui, il est complié, l'erreur mémoire est arrivé pendant l'exéction, syntaxiquement, aucune erreur, c'est une erreur de pointeur sur une classe non trouvée normalement...
    RTTI comme Runtime, le but c'est justement de résoudre le type à l'exécution, tu n'as pas compris ma remarque !

    Si la TStringList n'est pas EXPLICITEMENT utilisé, je pense que le compilateur de n'inclue pas la classe (ou lien BPL) dans ton projet, le type n'existe donc pas !

    Citation Envoyé par Moez.B Voir le message
    ... ça liste toutes les méthodes de la classe TButton.
    la tu fais un appel explicite à la référence de classe TButton, donc dès la compilation il y a une dépendance, c'est différent de ...Contexte.FindType('TButton')... où l'utilisation d'une chaine retire la dépendance
    Citation Envoyé par Moez.B Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonType             := Contexte.GetType(TStringList);
    ça ne marche pas, pour la simple raison qu'on doit passer un pointeur comme paramètre,
    Tu viens de faire la même chose dans ...GetType(TButton)..., tu te contredis !
    Tu confonds GetType et FindType

    Citation Envoyé par Moez.B Voir le message
    : Mon but est d'explorer , je veux simuler l'instanciation d'une TStringList, l'appel à ses méthodes en utilisant les RTTI, travailler aussi avec les attributes Après peut être que je vais travailler sur une partie d'automatisation de traitement déjà existant...
    Maitrise tu déjà TMethod et MethodAddress des RTTI classique, sache que déjà tu peux évoquer des méthodes, ensuite GetStrProp pour une propriété chaine, tu as les variantes Ord, Bool, Double ...
    Comment modifier une propriété par son nom ?

    Citation Envoyé par Moez.B Voir le message
    : niveau de compréhension : 0% dans tu ce que tu as mentionné ici
    Pourtant, c'est des concepts bien plus anciens (plus populaires en Java) que les nouvelles RTTI, c'est des Design Patterns,
    faire de la POO c'est un début,
    appliquer les Pattern c'est prendre la précaution d'éviter de faire n'importe quoi avec des objets !

  5. #5
    Membre averti Avatar de Moez.B
    Homme Profil pro
    Développeur Delphi
    Inscrit en
    Mars 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Tunisie

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 219
    Points : 370
    Points
    370
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    RTTI comme Runtime, le but c'est justement de résoudre le type à l'exécution, tu n'as pas compris ma remarque !

    Si la TStringList n'est pas EXPLICITEMENT utilisé, je pense que le compilateur de n'inclue pas la classe (ou lien BPL) dans ton projet, le type n'existe donc pas !



    la tu fais un appel explicite à la référence de classe TButton, donc dès la compilation il y a une dépendance, c'est différent de ...Contexte.FindType('TButton')... où l'utilisation d'une chaine retire la dépendance

    Tu viens de faire la même chose dans ...GetType(TButton)..., tu te contredis !
    Tu confonds GetType et FindType


    Maitrise tu déjà TMethod et MethodAddress des RTTI classique, sache que déjà tu peux évoquer des méthodes, ensuite GetStrProp pour une propriété chaine, tu as les variantes Ord, Bool, Double ...
    Comment modifier une propriété par son nom ?


    Pourtant, c'est des concepts bien plus anciens (plus populaires en Java) que les nouvelles RTTI, c'est des Design Patterns,
    faire de la POO c'est un début,
    appliquer les Pattern c'est prendre la précaution d'éviter de faire n'importe quoi avec des objets !
    Eh bien merci pour toutes ces précieuses remarque, de la POO je fais, du RTTI, non. En faite, les choses se mélangeait d'après ce que j'ai compris entre les anciens concepts de la RTTI ( je crois que ça date de la version 1 de Delphi ) et toutes ces nouveautés ... je suis entrain de suivre des cours sur les RTTI en Delphi.. là, je commence, je veux exploiter les notions que j'ai apprises et ça se bloque au premier coup .. eh ben, ce n'est pas facile ... les Design Pattern, il faut aussi approfondir ses connaissances ... POO puis Design Pattern ... Ok .. je m'y mets ... :

Discussions similaires

  1. Erreur d'appel au constructeur
    Par Invité dans le forum Débuter
    Réponses: 6
    Dernier message: 29/05/2014, 14h42
  2. erreur invocation de méthode ws
    Par futuring dans le forum Services Web
    Réponses: 0
    Dernier message: 22/06/2011, 17h54
  3. Réponses: 1
    Dernier message: 26/11/2006, 17h42
  4. [Language][Héritage] Erreur à propos du constructeur
    Par zizou771 dans le forum Langage
    Réponses: 4
    Dernier message: 12/09/2005, 17h48

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