Delphi RIO - Ansi to string cast does not work when Ansi string is part of array of const

Viewed 198

I'm using Delphi RIO 10.3.3.

When I pass Ansi string as one of the elements of array of const, string() cast does not work on it. To make it work, I have to cast VAnsiString to AnsiString() first and then apply String() cast.

Most of the similar examples I have seen on net, use direct String() casting.

Is it a bug in RIO or am I missing something?

function TForm1.VarRecToStr(AVarRec: TVarRec): string;
  const
    Bool : array[Boolean] of string = ('False', 'True');
begin
    case AVarRec.VType of
      vtInteger:    Result := IntToStr(AVarRec.VInteger);
      vtBoolean:    Result := Bool[AVarRec.VBoolean];
      vtChar:       Result := AVarRec.VChar;
      vtExtended:   Result := FloatToStr(AVarRec.VExtended^);
      vtString:     Result := AVarRec.VString^;
      vtPChar:      Result := AVarRec.VPChar;
      vtObject:     Result := AVarRec.VObject.ClassName;
      vtClass:      Result := AVarRec.VClass.ClassName;
      //vtAnsiString: Result := string(AnsiString(AVarRec.VAnsiString));
      vtAnsiString: Result := string(AVarRec.VAnsiString);
      vtCurrency:   Result := CurrToStr(AVarRec.VCurrency^);
      vtVariant:    Result := string(AVarRec.VVariant^);
      vtWideString: Result := string(WideString(AVarRec.VWideString));
      vtUnicodeString:
                    Result := string(AVarRec.VUnicodeString);
    else
      result := '';
    end;
end;


function TForm1.VarArrayToStr(AVarArray: array of const): string;
  var
    i : integer;
begin
    result := '';
    for i := 0 to High(AVarArray) do
      result := result + VarRecToStr( AVarArray[i] );
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  w: WideString;
  s: shortstring;
  an: Ansistring;
begin
  //
  w := 'Wide';
  s := 'Short';
  an := 'Ansi';
  ShowMessage(VarArrayToStr([w,s,an, 10]));
end;

Output:

enter image description here

Code credits to: How do I build an array of const?

1 Answers

Like UnicodeString and WideString, an AnsiString is stored in a TVarRec as an untyped pointer to its data payload. You have to cast that pointer to AnsiString (or at least to PAnsiChar) in order for the RTL to access the AnsiString's data properly (including its StrRec header, if needed). You are trying to type-cast the untyped Pointer as-is directly to UnicodeString, which will not work. The compiler will accept that, but it will assume the pointer is to a UnicodeString's payload, not to an AnsiString's payload. As such, you need to type-cast the pointer to PAnsiChar or AnsiString so that the RTL knows to convert the data from ANSI to Unicode during the assignment to a UnicodeString.

Related