Question

J'essaie d'analyser des objets au format XML dans Delphi. Je me suis donc renseigné sur l'appel de la méthode ClassInfo de l'objet pour obtenir ses informations RTTI.

En fait, cela ne fonctionne apparemment que pour les objets TPersistent. Sinon, je dois spécifiquement ajouter une directive de compilation {$ M +} au code source du compilateur pour générer des informations RTTI.

J'ai donc heureusement ajouté la directive, seulement pour constater que, même si elle renvoyait quelque chose de l'appel ClassInfo (elle renvoyait nil), je ne peux plus récupérer les propriétés, les champs ou les méthodes de la classe. C'est comme s'il créait l'objet vide.

Une idée de ce qui me manque ici? Merci!

Était-ce utile?

La solution

Avez-vous mis ces propriétés et méthodes dans la section published ?

De plus, RTTI 'classique' ($ TYPEINFO ON) ne vous fournira des informations que sur les propriétés, pas sur les méthodes. Vous avez besoin du RTTI 'étendu' ($ METHODINFO ON) pour ceux-là.

Bon point de départ pour les informations RTTI étendues: David Glassborow sur RTTI étendu

(qui pourrait croire que cette minute à peine, j'ai fini d'écrire du code qui utilise RTTI étendu et j'ai décidé de parcourir un peu le débordement de pile:))

Autres conseils

RTTI ne vous montrera que les publications publiées, etc. - pas seulement les publics.

Essayez votre code avec un objet TO et voyez ce qui se passe - si cela ne fonctionne pas, postez votre code car tout le monde n'est pas psychique.

Avez-vous envisagé d'utiliser le composant TXMLDocument? Il examinera votre code XML, puis créera une belle unité de classes Delphi représentant votre fichier XML, ce qui facilite grandement la lecture et l'écriture de fichiers XML.

En ce qui concerne le problème RttiType renvoyant uniquement nil, cela se produit probablement pour une raison: lors de votre test, vous n'avez instancié la classe à aucun moment. Le compilateur, parce qu'il n'a jamais de référence à cette classe (car ce n'est pas du tout une instance), la supprime simplement des informations sous forme d'optimisation. Voir les deux exemples ci-dessous. Le comportement est différent lorsque la classe est instanciée à un moment donné dans votre code ou non.

Supposons la classe suivante:

type
  TTest = class
  public
    procedure Test;
  end;

et le code suivant ci-dessous:

var
  LContext: TRttiContext;
  LType: TRttiType;
  LTest: TTest;
begin
  LContext := TRttiContext.Create;
  for LType in LContext.GetTypes do
  begin
    if LType.IsInstance then
    begin
      WriteLn(LType.Name);
    end;
  end;
end;

Jusqu'à présent, les informations de classe TTest ne sont pas disponibles pour une utilisation par RTTI. Cependant, lorsque nous créons à un moment donné dans l'application, une référence est créée pour celle-ci dans la compilation, ce qui rend cette information disponible:

var
  LContext: TRttiContext;
  LType: TRttiType;
  LTest: TTest;
begin
  LTest := TTest.Create; //Here i´m using TTest.
                         //Could be in another part of the program

  LContext := TRttiContext.Create;
  for LType in LContext.GetTypes do
  begin
    if LType.IsInstance then
    begin
      WriteLn(LType.Name);
    end;
  end;
end;

À ce stade, si vous utilisez LContext.FindType ('TTest') , il n'y aura pas de retour nul, car le compilateur conserve la référence à la classe. Ceci explique le comportement que vous aviez dans vos tests.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top