rtti для record

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

rtti для record

Сообщение zub » 06.09.2016 02:38:44

Захотелось в рантайме разобрать некий record по составным частям.
В дельфи для этого есть модуль rtti с TRttiContext, например такой код
Код: Выделить всё
program Project1;
{$APPTYPE CONSOLE}
uses
  SysUtils,Rtti;
type
  TmyRecord = record
    aValue: String;
    aNumber: Real;
    Morenumbers: Integer;
  end;
var
  m: TMyRecord;
  rtype: TRTTIType;
  fields: TArray<TRttiField>;
  i: Integer;
begin
  m.aValue := 'OK';
  m.aNumber := Pi;
  m.Morenumbers := 666;
  rtype := TRTTIContext.Create.GetType(TypeInfo(TMyrecord));
  writeln(rtype.ToString);
  fields := rtype.GetFields;
  for i := 0 to High(fields) do
    writeln(Format('%s: %s :: %s', [
      fields[i].Name,
      fields[i].FieldType.ToString,
      fields[i].GetValue(@m).ToString]));
  readln;
end.

выводит
Код: Выделить всё
TmyRecord
aValue: string :: OK
aNumber: Real :: 3,14159265358979
Morenumbers: Integer :: 666

В FPC модуля rtti нет и такое не реализуемо? или есть другие способы?

Добавлено спустя 58 минут 53 секунды:
разобрался. неправильно понял в описании TTypeData
Код: Выделить всё
            tkRecord:
              (
                RecSize: Integer;
                ManagedFldCount: Integer;
                {ManagedFields: array[1..ManagedFldCount] of TManagedField}
              );

там таки лежит массивчик TManagedField. Пусть и нетак красиво как в делфи, но можно сделать

Добавлено спустя 34 минуты 35 секунд:
Хм. а вот имя поля записи не получить((
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: rtti для record

Сообщение zub » 09.09.2016 09:19:13

С темой всё более-менее ясно. теперь офтопик про делфи))
Я грешным делом поначалу подумал что TRTTIContext это класс, просто в примере забыт деструктор. Но это
Код: Выделить всё
  TRttiContext = record
  private
    FContextToken: IInterface;
  public
    class function Create: TRttiContext; static;
    procedure Free;
   
    function GetType(ATypeInfo: Pointer): TRttiType; overload;
    function GetType(AClass: TClass): TRttiType; overload;
    function GetTypes: TArray<TRttiType>;
    function FindType(const AQualifiedName: string): TRttiType;
    function GetPackages: TArray<TRttiPackage>;
  end;

В чем прикол работы с рекордом какбудьто с классом? и вообще нафиг рекорд а не класс сразу?
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: rtti для record

Сообщение wavebvg » 09.09.2016 10:44:43

zub писал(а):В чем прикол работы с рекордом какбудьто с классом? и вообще нафиг рекорд а не класс сразу?

Потому что RECORD можно просто физически скопировать, а значит и контекст утащить куда-то далеко наверх.
И да, если посмотреть, как это дело всё работает, то возникнет куда больше вопросов, особенно, зачем интерфейс делать nil каждый раз.
wavebvg
постоялец
 
Сообщения: 354
Зарегистрирован: 28.02.2008 04:57:35


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 20

Рейтинг@Mail.ru