I am looking for a simple and ideally general (or using generics) way to convert an array to an array of const (=array of TVarRec). My specific case is that I have an array of Variant and want to pass it to the Format() function.
This is what I've found so far, but it looks hackish to me:
function MyFormat(const Fmt: string; const Args: TArray<Variant>): string;
var
A: array of TVarRec;
I: Integer;
begin
SetLength(A, Length(Args));
for I:= Low(Args) to High(Args) do begin
A[I].VType:= vtVariant;
A[I].VVariant:= @Args[I];
end;
Result:= Format(Fmt, A);
end;
It seems to work. Is it safe?
Could it be done shorter, better, faster, or can I use something ready instead? :)
Just some additional thoughts and fun facts:
System.Rtti.TValue recently became my friend. However, it seems it is missing a feature here. I am able to read my array using TValue.From(), but it seems there is no way to get it out as array of TVarRec. There is a wonderful TValueArrayToArrayOfConst, but it doesn't really help, because I had to construct an array of TValue first, which is different from an array stored in a single TValue... :(
At least TValue is able to output a single element as TVarRec, so I thought I could create a generic converter for all types of arrays. But...
Would you think this works?
for I:= Low(Args) to High(Args) do A[I]:= TValue.From(Args[I]).AsVarRec;
It compiles, but TValue's memory is released after use, and since TVarRec.VVariant is a pointer, it then points to some old location which is overridden on next cycle.
TVarRecand read Array of const for an explanation of howTVarRecworks. Your code "works" becauseTVarRecreally does pass around aVariantby pointer.