Recent

Author Topic: How write RTTI functions?  (Read 967 times)

J-23

  • Full Member
  • ***
  • Posts: 108
How write RTTI functions?
« on: May 30, 2020, 12:57:42 am »
Hello
Do you know the information about how the rtti function is created?

eljo

  • Sr. Member
  • ****
  • Posts: 468
Re: How write RTTI functions?
« Reply #1 on: May 30, 2020, 01:06:08 am »
What?  can you be a bit more specific on what you want to do?

Do you want to enable RTTI for your classes?
In this case take a look on {$M+} or inherit your classes from TPersistent.

Do you want to use RTTI to write extra functionality?
In this case take a look on the unit typinfo and the RTTI Controls Package that's included with lazarus.

Something else outside my imagination? 

J-23

  • Full Member
  • ***
  • Posts: 108
Re: How write RTTI functions?
« Reply #2 on: May 30, 2020, 02:47:57 am »
What?  can you be a bit more specific on what you want to do?

Do you want to enable RTTI for your classes?
In this case take a look on {$M+} or inherit your classes from TPersistent.

Do you want to use RTTI to write extra functionality?
In this case take a look on the unit typinfo and the RTTI Controls Package that's included with lazarus.

I know that.

It's about how RTTI functions are created


For example, how do you know that the function:
Code: Pascal  [Select][+][-]
  1. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  2. var
  3.   hp : PTypeData;
  4.   i : longint;
  5.   p : shortstring;
  6.   pd : ^TPropData;
  7. begin
  8.   P:=PropName;  // avoid Ansi<->short conversion in a loop
  9.   while Assigned(TypeInfo) do
  10.     begin
  11.       // skip the name
  12.       hp:=GetTypeData(Typeinfo);
  13.       // the class info rtti the property rtti follows immediatly
  14.       pd:=aligntoptr(pointer(pointer(@hp^.UnitName)+Length(hp^.UnitName)+1));
  15.       Result:=PPropInfo(@pd^.PropList);
  16.       for i:=1 to pd^.PropCount do
  17.         begin
  18.           // found a property of that name ?
  19.           if ShortCompareText(Result^.Name, P) = 0 then
  20.             exit;
  21.           // skip to next property
  22.           Result:=PPropInfo(aligntoptr(pointer(@Result^.Name)+byte(Result^.Name[0])+1));
  23.         end;
  24.       // parent class
  25.       Typeinfo:=hp^.ParentInfo;
  26.     end;
  27.   Result:=Nil;
  28. end;
  29.  
It has to look like this

eljo

  • Sr. Member
  • ****
  • Posts: 468
Re: How write RTTI functions?
« Reply #3 on: May 30, 2020, 06:18:37 am »
What?  can you be a bit more specific on what you want to do?

Do you want to enable RTTI for your classes?
In this case take a look on {$M+} or inherit your classes from TPersistent.

Do you want to use RTTI to write extra functionality?
In this case take a look on the unit typinfo and the RTTI Controls Package that's included with lazarus.

I know that.

It's about how RTTI functions are created


For example, how do you know that the function:
Code: Pascal  [Select][+][-]
  1. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  2. var
  3.   hp : PTypeData;
  4.   i : longint;
  5.   p : shortstring;
  6.   pd : ^TPropData;
  7. begin
  8.   P:=PropName;  // avoid Ansi<->short conversion in a loop
  9.   while Assigned(TypeInfo) do
  10.     begin
  11.       // skip the name
  12.       hp:=GetTypeData(Typeinfo);
  13.       // the class info rtti the property rtti follows immediatly
  14.       pd:=aligntoptr(pointer(pointer(@hp^.UnitName)+Length(hp^.UnitName)+1));
  15.       Result:=PPropInfo(@pd^.PropList);
  16.       for i:=1 to pd^.PropCount do
  17.         begin
  18.           // found a property of that name ?
  19.           if ShortCompareText(Result^.Name, P) = 0 then
  20.             exit;
  21.           // skip to next property
  22.           Result:=PPropInfo(aligntoptr(pointer(@Result^.Name)+byte(Result^.Name[0])+1));
  23.         end;
  24.       // parent class
  25.       Typeinfo:=hp^.ParentInfo;
  26.     end;
  27.   Result:=Nil;
  28. end;
  29.  
It has to look like this
To put it  as simple as I can, RTTI is a record that contains information about the class in question.
The record  is defined inside the compiler and can not be extended by the end user.

You can find out the record's definition by ctrl+click on the PTypeInfo, TPropData etc data types to jump to their declarations.  Ppressing F1 on the name of the type (and if the help  system manages to function properly) you will see  the documentation on the types.

Now most of the RTTI functions are nothing more than using the information about the type to decide how to do what ever they need to do.

With out a specific goal in mind there is no way to explain how to use it or why.

Take a closer look on Get/Set PropValue()  for an overview.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: How write RTTI functions?
« Reply #4 on: May 30, 2020, 10:57:02 am »
It's about how RTTI functions are created


For example, how do you know that the function:
Code: Pascal  [Select][+][-]
  1. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  2. var
  3.   hp : PTypeData;
  4.   i : longint;
  5.   p : shortstring;
  6.   pd : ^TPropData;
  7. begin
  8.   P:=PropName;  // avoid Ansi<->short conversion in a loop
  9.   while Assigned(TypeInfo) do
  10.     begin
  11.       // skip the name
  12.       hp:=GetTypeData(Typeinfo);
  13.       // the class info rtti the property rtti follows immediatly
  14.       pd:=aligntoptr(pointer(pointer(@hp^.UnitName)+Length(hp^.UnitName)+1));
  15.       Result:=PPropInfo(@pd^.PropList);
  16.       for i:=1 to pd^.PropCount do
  17.         begin
  18.           // found a property of that name ?
  19.           if ShortCompareText(Result^.Name, P) = 0 then
  20.             exit;
  21.           // skip to next property
  22.           Result:=PPropInfo(aligntoptr(pointer(@Result^.Name)+byte(Result^.Name[0])+1));
  23.         end;
  24.       // parent class
  25.       Typeinfo:=hp^.ParentInfo;
  26.     end;
  27.   Result:=Nil;
  28. end;
  29.  
It has to look like this

We know it has to look like this because we (as in the compiler developers) implement both the binary format and the functions to access them, so that you (as in a Object Pascal user) don't have to care about this. If you want to implement your own functions to work on the existing RTTI data, then you need to learn how the RTTI data is structured (for example by looking at the provided RTTI functionality in units TypInfo and Rtti (the latter is new in FPC 3.2) or by looking at the code in FPC that generates it).

 

TinyPortal © 2005-2018