Recent

Author Topic: [SOLVED] Work with array property  (Read 439 times)

Okoba

  • Hero Member
  • *****
  • Posts: 651
[SOLVED] Work with array property
« on: January 28, 2026, 06:27:27 pm »
Hello,
In this sample can you tell me how can I correctly get length of the array, and add or delete elements to it? I can cast it to Integer array but I like to know the generic way that works for all element types.
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$mode objfpc}{$H+}
  3. {$M+}
  4. {$RTTI EXPLICIT
  5.    PROPERTIES([vcPrivate,vcProtected,vcPublic,vcPublished])
  6.    FIELDS([vcPrivate,vcProtected,vcPublic,vcPublished])
  7.    METHODS([vcPrivate,vcProtected,vcPublic,vcPublished])}
  8. uses
  9.   TypInfo;
  10.  
  11. type
  12.   TTest = record
  13.     A: array of integer;
  14.   end;
  15. var
  16.   T: TTest;
  17.   FieldTable: PExtendedFieldInfoTable;
  18.   FieldCount, I: Integer;
  19. begin
  20.   T.A := [1, 2, 3];
  21.   FieldCount := GetFieldList(TypeInfo(TTest), FieldTable);
  22.   for I := 0 to FieldCount - 1 do
  23.     with FieldTable^[I]^ do
  24.     begin
  25.       if Name^ = 'A' then
  26.       begin
  27.       How to get the array length?
  28.       How to add another item to the array?
  29.       end;
  30.     end;
  31.   ReadLn;
  32. end.
  33.  
« Last Edit: February 01, 2026, 08:40:10 pm by Okoba »

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 404
  • I use FPC [main] 💪🐯💪
Re: Work with array property
« Reply #1 on: January 28, 2026, 07:52:57 pm »
It's scary, but it works

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$mode objfpc}{$H+}
  3. {$M+}
  4. {$RTTI EXPLICIT
  5.    PROPERTIES([vcPrivate,vcProtected,vcPublic,vcPublished])
  6.    FIELDS([vcPrivate,vcProtected,vcPublic,vcPublished])
  7.    METHODS([vcPrivate,vcProtected,vcPublic,vcPublished])}
  8. uses
  9.   TypInfo;
  10.  
  11. type
  12.   TTest = record
  13.     A: array of UInt64;
  14.   end;
  15. var
  16.   T: TTest;
  17.   FieldTable: PExtendedFieldInfoTable;
  18.   FieldCount, I: Integer;
  19.   newlen: SizeInt = 33;
  20. begin
  21.   T.A := [1, 2, 3];
  22.   FieldCount := GetFieldList(TypeInfo(TTest), FieldTable);
  23.   for I := 0 to FieldCount - 1 do
  24.     if FieldTable^[I]^.Name^ = 'A' then
  25.     begin
  26.       //How to get the array length?
  27.       WriteLn(DynArrayBounds(@PByte(@T)[FieldTable^[I]^.FieldOffset], FieldTable^[I]^.FieldType^)[0]+1);
  28.  
  29.       //How to add another item to the array?
  30.       DynArraySetLength(PPointer(@PByte(@T)[FieldTable^[I]^.FieldOffset])^, FieldTable^[I]^.FieldType^, 1, @newlen);
  31.     end;
  32.  
  33.   WriteLn(Length(T.A));
  34.   ReadLn;
  35. end.
I may seem rude - please don't take it personally

Okoba

  • Hero Member
  • *****
  • Posts: 651
Re: Work with array property
« Reply #2 on: January 29, 2026, 08:20:04 am »
Thank you!
Code: Pascal  [Select][+][-]
  1. PPointer(@PByte(@T)[FieldTable^[I]^.FieldOffset])^
This part is confusing? it is pointer of the array property?
How can i set the newly added element dynamically depending on the array element type? like if it is integer set it to 1 and if string set to '1'?

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 404
  • I use FPC [main] 💪🐯💪
Re: Work with array property
« Reply #3 on: January 29, 2026, 09:10:53 am »
Something like that, but I'm starting to dislike this code more and more

Besides, I'm still confused as to why I get the array element type this way. I originally wrote it differently, but it didn't work...

And this worked, but I don't have time to figure it out yet, so I'll leave it as is

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$mode objfpc}{$H+}
  3. {$M+}
  4. {$RTTI EXPLICIT
  5.    PROPERTIES([vcPrivate,vcProtected,vcPublic,vcPublished])
  6.    FIELDS([vcPrivate,vcProtected,vcPublic,vcPublished])
  7.    METHODS([vcPrivate,vcProtected,vcPublic,vcPublished])}
  8. uses
  9.   TypInfo;
  10.  
  11. type
  12.   TTest = record
  13.     A: array of Integer;
  14.   end;
  15. var
  16.   T: TTest;
  17.   FieldTable: PExtendedFieldInfoTable;
  18.   FieldCount, I: Integer;
  19.   newlen: SizeInt = 33;
  20.   s: string;
  21.   ptd: PTypeData;
  22. begin
  23.   T.A := [1, 2, 3];
  24.   FieldCount := GetFieldList(TypeInfo(TTest), FieldTable);
  25.   for I := 0 to FieldCount - 1 do
  26.     if FieldTable^[I]^.Name^ = 'A' then
  27.     begin
  28.       //How to get the array length?
  29.       WriteLn(DynArrayBounds(@PByte(@T)[FieldTable^[I]^.FieldOffset], FieldTable^[I]^.FieldType^)[0]+1);
  30.  
  31.       //How to add another item to the array?
  32.       DynArraySetLength(PPointer(@PByte(@T)[FieldTable^[I]^.FieldOffset])^, FieldTable^[I]^.FieldType^, 1, @newlen);
  33.  
  34.       WriteStr(s, FieldTable^[I]^.FieldType^^.Kind);
  35.       WriteLn(s);
  36.  
  37.       case FieldTable^[I]^.FieldType^^.Kind of
  38.         tkUnknown:;
  39.         tkInteger:;
  40.         tkChar:;
  41.         tkEnumeration:;
  42.         tkFloat:;
  43.         tkSet:;
  44.         tkMethod:;
  45.         tkSString:;
  46.         tkLString:;
  47.         tkAString:;
  48.         tkWString:;
  49.         tkVariant:;
  50.         tkArray:;
  51.         tkRecord:;
  52.         tkInterface:;
  53.         tkClass:;
  54.         tkObject:;
  55.         tkWChar:;
  56.         tkBool:;
  57.         tkInt64:;
  58.         tkQWord:;
  59.         tkDynArray:
  60.         begin
  61.           ptd:=GetTypeData(FieldTable^[I]^.FieldType^);
  62.  
  63.           case ptd^.OrdType of
  64.             otSLong: PInteger(PPointer(@PByte(@T)[FieldTable^[I]^.FieldOffset])^)[3]:=44;
  65.           end;
  66.  
  67.         end;
  68.         tkInterfaceRaw:;
  69.         tkProcVar:;
  70.         tkUString:;
  71.         tkUChar:;
  72.         tkHelper:;
  73.         tkFile:;
  74.         tkClassRef:;
  75.         tkPointer:;
  76.       end;
  77.  
  78.     end;
  79.  
  80.   WriteLn(Length(T.A));
  81.   WriteLn(T.A[0]);
  82.   WriteLn(T.A[1]);
  83.   WriteLn(T.A[2]);
  84.   WriteLn(T.A[3]);
  85.   WriteLn(T.A[4]);
  86.   ReadLn;
  87. end.
I may seem rude - please don't take it personally

PascalDragon

  • Hero Member
  • *****
  • Posts: 6353
  • Compiler Developer
Re: Work with array property
« Reply #4 on: January 29, 2026, 09:02:01 pm »
Code: Pascal  [Select][+][-]
  1. PPointer(@PByte(@T)[FieldTable^[I]^.FieldOffset])^
This part is confusing? it is pointer of the array property?

It's a field, not a property.

 

TinyPortal © 2005-2018