Delphi RIO - Il cast da Ansi a stringa non funziona quando la stringa Ansi fa parte dell'array di const

Aug 20 2020

Sto usando Delphi RIO 10.3.3.

Quando passo Ansi string come uno degli elementi dell'array di const, string() cast non funziona su di esso. Per farlo funzionare, devo prima eseguire il cast di VAnsiString su AnsiString() e quindi applicare il cast di String().

La maggior parte degli esempi simili che ho visto in rete utilizza il casting diretto di String().

È un bug in RIO o mi sto perdendo qualcosa?

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;

Produzione:

Codice crediti a: Come posso creare un array di const?

Risposte

6 RemyLebeau Aug 20 2020 at 22:02

Come UnicodeStringe WideString, an AnsiStringè memorizzato in a TVarReccome puntatore non tipizzato al suo payload di dati. Devi trasmettere quel puntatore a AnsiString(o almeno a PAnsiChar) affinché RTL acceda AnsiStringcorrettamente ai dati di (inclusa la sua StrRecintestazione, se necessario). Stai tentando di eseguire il cast del tipo non tipizzato Pointer così com'è direttamente in UnicodeString, che non funzionerà. Il compilatore lo accetterà, ma presumerà che il puntatore sia a un UnicodeStringpayload di , non a un AnsiStringpayload di . Pertanto, è necessario eseguire il cast del puntatore a PAnsiCharo in AnsiStringmodo che RTL sappia convertire i dati da ANSI a Unicode durante l'assegnazione a un file UnicodeString.