Friday, March 4, 2011

Delphi RTTI trouble: GetPropInfo returns nil with {$METHODINFO ON}!?

Is there any possibility that GetPropInfo returns nil even if the given class is declared with correct {$METHODINFO} directives.

  type 
  ... 
  ...
    {$METHODINFO ON}
    TMyClass = class
    private
      fField: integer;
    published
      property Field: integer read fField write fField;
    end;
    {$METHODINFO OFF}
  ...
  ...
  procedure TestRTTI;
  begin
    assert(assigned(GetPropInfo(TMyClass, 'Field')), 'WTF! No RTTI found!');
  end;
From stackoverflow
  • Gotcha! It seems the problem is hidden at the forward declaration that I overlooked. Didn't know that sneaky feature.

    It seems the compiler considers only the first declaration of the class to generate RTTI or not so if you have a forward declaration like this...

      type 
        TMyClass = class;   
        ...    
        ...
        {$METHODINFO ON}
        TMyClass = class
        private
          fField: integer;
        published
          property Field: integer read fField write fField;
        end;
        {$METHODINFO OFF}   
        ...   
        ...   
        procedure TestRTTI;   
        begin
          assert(assigned(GetPropInfo(TMyClass, 'Field')), 'WTF! No RTTI found!');   
        end;
    

    ... You will get the assertion error. So, for getting the RTTI right, one needs to turn the {$METHODINFO} directive on for the forward declaration, as seen here....

      type 
        {$METHODINFO ON}
        TMyClass = class;   
        {$METHODINFO OFF}   
        ...    
        ...
        TMyClass = class
        private
          fField: integer;
        published
          property Field: integer read fField write fField;
        end;
        ...
    
    TOndrej : I've come across this "feature" already, too. BTW, it's not necesarry to turn on the full {$METHODINFO ON}, it's enough to just use {$TYPEINFO ON}, or {$M+}.
    Mason Wheeler : It should be noted that in Delphi 2009, the compiler adds {M+} to any class with a "published" section automatically, so this problem no longer exists.
  • Hi!

    I am glad that you have found a solution. It is the same thing with $TypeInfo directive. Delphi 7 help says:

    "Note that if a class is forward declared, the first declaration of the class must be declared with the $M switch."

    Regards.

    Al Gonzalez. :)

    P.S.: $M+/- = $TypeInfo On/Off

0 comments:

Post a Comment