Delphi RIO - Ansi to string cast не работает, если строка Ansi является частью массива const

Aug 20 2020

Я использую Delphi RIO 10.3.3.

Когда я передаю строку Ansi как один из элементов массива const, приведение строки () к нему не работает. Чтобы заставить его работать, мне нужно сначала преобразовать VAnsiString в AnsiString (), а затем применить приведение String ().

Большинство подобных примеров, которые я видел в сети, используют прямое приведение String ().

Это ошибка в RIO или я что-то упускаю?

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;

Выход:

Авторы кода: Как мне построить массив констант?

Ответы

6 RemyLebeau Aug 20 2020 at 22:02

Как UnicodeStringи WideString, an AnsiStringхранится в a TVarRecкак нетипизированный указатель на его полезные данные. Вы должны привести этот указатель к AnsiString(или, по крайней мере, к PAnsiChar), чтобы RTL мог правильно получить доступ к AnsiStringданным (включая его StrRecзаголовок, если необходимо). Вы пытаетесь ввести нетипизированное Pointer как есть напрямую в тип UnicodeString, но это не сработает. Компилятор примет это, но он будет считать, что указатель указывает на UnicodeStringполезную нагрузку, а не на AnsiStringполезную нагрузку. Таким образом, вам необходимо привести указатель к типу PAnsiCharили AnsiStringтак, чтобы RTL знал, что нужно преобразовать данные из ANSI в Unicode во время присвоения файлу UnicodeString.