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 :

Problème RTTI et Record


Sujet :

Delphi

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Mai 2015
    Messages : 4
    Points : 4
    Points
    4
    Par défaut Problème RTTI et Record
    Bonjour,

    Cela fait des heures que je me prends la tête avec l'utilisation de RTTI sous Delphi XE6...

    Je n'arrives pas à lister tous les noms / valeurs d'un record aussi bête que IMAGE_DOS_HEADER défini dans Windows.pas.

    J'ai remarqué que le problème survient quand il tombe sur un array, logique semble t-il car il faudrait pouvoir aller plus en proffondeur, cependant j'ai essayé plein de méthodes j'obtiens à chaque fois une violation d’accès ou une exception "EInsufficientRTTI".

    Des idées ???

    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
     
    var i           : integer;
    fields      : TArray<TRTTIField>;
    field       : TRTTIField;
     
    RTTIType    : TRTTIType;
    DosHeader : IMAGE_DOS_HEADER;
    begin
    allocconsole();
    RTTIType := TRTTIContext.Create.GetType(TypeInfo(IMAGE_DOS_HEADER));
     
    fields := RTTIType.getFields;
    for i := 0 to High(Fields) do begin
      field := Fields[i];
     
      writeln(field.Name);
      writeln(field.getValue(@DosHeader).toString); // ERROR SUR e_res ET e_res2 QUI SONT DES ARRAY
      writeln('----');
    end;
    La déclaration de IMAGE_DOS_HEADER de Windows.pas

    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
     
    _IMAGE_DOS_HEADER = record             { DOS .EXE header                  }
          e_magic: Word;                     { Magic number                     }
          e_cblp: Word;                      { Bytes on last page of file       }
          e_cp: Word;                        { Pages in file                    }
          e_crlc: Word;                      { Relocations                      }
          e_cparhdr: Word;                   { Size of header in paragraphs     }
          e_minalloc: Word;                  { Minimum extra paragraphs needed  }
          e_maxalloc: Word;                  { Maximum extra paragraphs needed  }
          e_ss: Word;                        { Initial (relative) SS value      }
          e_sp: Word;                        { Initial SP value                 }
          e_csum: Word;                      { Checksum                         }
          e_ip: Word;                        { Initial IP value                 }
          e_cs: Word;                        { Initial (relative) CS value      }
          e_lfarlc: Word;                    { File address of relocation table }
          e_ovno: Word;                      { Overlay number                   }
          e_res: array [0..3] of Word;       { Reserved words                   }
          e_oemid: Word;                     { OEM identifier (for e_oeminfo)   }
          e_oeminfo: Word;                   { OEM information; e_oemid specific}
          e_res2: array [0..9] of Word;      { Reserved words                   }
          _lfanew: LongInt;                  { File address of new exe header   }
      end;
    Remarque: je ne peux même pas tester quand j'arrive à e_res ou e_res2 si c'est un array, dés que je fais appel à la méthode getValue ça plante directe!

    Je suis totalement perdu pour ce qu'il semble pourtant être quelque chose de très simple.

    Merci d'avance pour votre précieuse aide !

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    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 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    e_res: array [0..3] of Word;
    C'est compliqué de faire un AsString sur ce genre de valeur, un tableau comme cela pourrait être une suite de 4 valeurs mais aussi un Int64 découpé en 4 parties, la RTTI ne peut pas deviner ce que représente ce genre de valeur
    une liste sérializée a souvent un séparateur entre chaque item ...

    array [0..3] of Word n'est pas un type, il n'y a pas de RTTI puisque c'est une déclaration anonyme
    C'est le même problème entre array of string et TStringDynArray !
    Seul le dernier peut être utilisé comme type de retour d'une fonction, c'est une limitation connu du compilateur, les RTTI doivent avoir les memes


    De plus, si l'on regarde le code de ToString :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tkArray: Result := '(array)'; // do not localize
    la sortie n'est pas très intéressante pour un élément tableau

    fait ta propre déclaration (juste pour tester)

    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
     
    type
      TWordQuadArray = array [0..3] of Word;
      TWordTenArray = array [0..9] of Word;
      IMAGE_DOS_HEADER = record             { DOS .EXE header                  }
          e_magic: Word;                     { Magic number                     }
          e_cblp: Word;                      { Bytes on last page of file       }
          e_cp: Word;                        { Pages in file                    }
          e_crlc: Word;                      { Relocations                      }
          e_cparhdr: Word;                   { Size of header in paragraphs     }
          e_minalloc: Word;                  { Minimum extra paragraphs needed  }
          e_maxalloc: Word;                  { Maximum extra paragraphs needed  }
          e_ss: Word;                        { Initial (relative) SS value      }
          e_sp: Word;                        { Initial SP value                 }
          e_csum: Word;                      { Checksum                         }
          e_ip: Word;                        { Initial IP value                 }
          e_cs: Word;                        { Initial (relative) CS value      }
          e_lfarlc: Word;                    { File address of relocation table }
          e_ovno: Word;                      { Overlay number                   }
          e_res: TWordQuadArray ;       { Reserved words                   }
          e_oemid: Word;                     { OEM identifier (for e_oeminfo)   }
          e_oeminfo: Word;                   { OEM information; e_oemid specific}
          e_res2: TWordTenArray ;      { Reserved words                   }
          _lfanew: LongInt;                  { File address of new exe header   }
      end;
    tu forces un nomage du type
    puis sans tester j'écrirais ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if field.getValue(@DosHeader).IsArray() then
    begin
      for J := 0 to field.getValue(@DosHeader).GetArrayLength - 1 do
        writeln(field.getValue(@DosHeader).GetArrayElement(J).toString);
    end
    else
      writeln(field.getValue(@DosHeader).toString);
    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
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Mai 2015
    Messages : 4
    Points : 4
    Points
    4
    Par défaut
    Merci !!!!!!

    Je n'avais pas pensé à modifier les déclarations pour supporter le RTTI.

    C'est domage que l'IDE ne supporte toujours pas la possibilité de gérer des array anonymes

    +11

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

Discussions similaires

  1. [Lazarus] RTTI sur record
    Par larsal007 dans le forum Lazarus
    Réponses: 1
    Dernier message: 08/01/2015, 11h59
  2. D6 : Problème avec un record en retour de fonction
    Par sevyc64 dans le forum Langage
    Réponses: 10
    Dernier message: 17/08/2014, 21h25
  3. Problème de type RECORD dans PGSQL
    Par wangying dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 29/01/2013, 16h19
  4. Problème durant le recording de TestComplete
    Par Lynaria dans le forum Test
    Réponses: 0
    Dernier message: 10/03/2010, 08h44
  5. Réponses: 4
    Dernier message: 10/12/2005, 20h52

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