2

I'm trying to parse objects to XML in Delphi, so I read about calling the object's ClassInfo method to get its RTTI info.

The thing is, this apparently only works for TPersistent objects. Otherwise, I have to specifically add a compiler directive {$M+} to the source code for the compiler to generate RTTI info.

So I happily added the directive, only to find that, even if it did return something from the ClassInfo call (it used to return nil), now I cannot retrieve the class' properties, fields or methods from it. It's like it created the object empty.

Any idea what am I missing here? Thanks!

4 Answers 4

7

Did you put those properties and methods into the published section?

Besides that, 'classical' RTTI ($TYPEINFO ON) will only get you information on properties, not on methods. You need 'extended' RTTI ($METHODINFO ON) for those.

Good starting point for extended RTTI: David Glassborow on extended RTTI

(who would believe that just this minute I finished writing some code that uses extended RTTI and decided to browse the Stack Overflow a little:))

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that has to be the problem. I was putting the properties on the public, not the published section. I'll have to wait for monday to try, since I do Delphy at work, and I'm home for the weekend already.
3

RTTI will only show you published properties,etc. - not just public ones.

Try your code with a TObject and see what happens - if that isn't working, post your code because not everyone is psychic.

2 Comments

That was the problem, my properties were just public, not published. Will try when I'm back at work on monday. Thanks!
Classic RTTI in delphi shows PUBLISHED properties, "new extended RTTI" can actually see everything, but requires a recent Delphi version (2010/XE or later).
3

Have you considered using the TXMLDocument component? It will look at your XML and then create a nice unit of Delphi classes that represents your XML file -- makes it really, really easy to read and write XML files.

1 Comment

TXMLDocument does that? I thought it was the XML Data Binding wizard that did that... ;)
0

As for the RttiType problem returning only nil, this probably occurs for one reason: in your test, you did not instantiate the class at any time. The compiler, because it never has a reference to this class (because it is not an instance at all), simply removes it from the information as a form of optimization. See the two examples below. The behavior is different when you have the class instantiated at some point in your code or not.

Suppose the following class:

type
  TTest = class
  public
    procedure Test;
  end;

and the following code below:

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;

so far, TTest class information is not available for use by RTTI. However, when we create at some point, within the application, then a reference is created for it within the compile, which makes this information available:

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;

At that point, if you use LContext.FindType ('TTest'), there will not be a nil return, because the compiler kept reference to the class. This explains the behavior you were having in your tests.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.