Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RTTI Dynamic array TValue Delphi 2010

I have a question. I am a newbie with Run Time Type Information from Delphi 2010. I need to set length to a dynamic array into a TValue. You can see the code.

Type TMyArray = array of integer;
TMyClass = class
publihed
function Do:TMyArray;
end;

function TMyClass.Do:TMyArray;
begin
SetLength(Result,5);
for i:=0 to 4 Result[i]=3;
end;
.......
.......
......
y:TValue;
Param:array of TValue;
.........
y=Methods[i].Invoke(Obj,Param);//delphi give me a DynArray type kind, is working, Param works to any functions.

if Method[i].ReturnType.TypeKind = tkDynArray then//is working...
begin
    I want to set length for y to 10000//i don't know how to write.
end;

I don't like Generics Collections.

like image 745
user558126 Avatar asked Dec 30 '10 09:12

user558126


1 Answers

TValue wasn't designed for arbitrary manipulation of its contents (it would have more helpers for e.g. setting record fields etc. if so), but rather for transporting values between concrete static types and dynamic RTTI. In this respect, TValue.SetArrayElement is an anomaly, and in hindsight, perhaps should not have been included. However, what you ask is possible:

uses Rtti;

type
  TMyArray = array of Integer;
  TMyClass = class
    function Go: TMyArray;
  end;

function TMyClass.Go: TMyArray;
var
  i: Integer;
begin
  SetLength(Result, 5);
  for i := 0 to 4 do
    Result[i] := 3;
end;

procedure P;
var
  ctx: TRttiContext;
  v: TValue;
  len: Longint;
  i: Integer;
begin
  v := ctx.GetType(TMyClass).GetMethod('Go').Invoke(TMyClass.Create, []);
  Writeln(v.ToString);
  len := 10;
  DynArraySetLength(PPointer(v.GetReferenceToRawData)^, v.TypeInfo, 1, @len);
  Writeln(v.GetArrayLength);
  for i := 0 to v.GetArrayLength - 1 do
    Writeln(v.GetArrayElement(i).ToString);
end;

begin
  P;
end.
like image 139
Barry Kelly Avatar answered Nov 10 '22 15:11

Barry Kelly