Delphi RIO - 当 Ansi 字符串是 const 数组的一部分时,Ansi 到字符串的转换不起作用
Delphi RIO - Ansi to string cast does not work when Ansi string is part of array of const
我正在使用 Delphi RIO 10.3.3。
当我将 Ansi 字符串作为 const 数组的元素之一传递时,string() 转换对其不起作用。为了让它工作,我必须先将 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;
输出:
代码归功于:How do I build an array of const?
与 UnicodeString
和 WideString
一样,AnsiString
作为指向其数据的 未类型化 指针存储在 TVarRec
中有效载荷。您必须将该指针转换为 AnsiString
(或至少转换为 PAnsiChar
),以便 RTL 正确访问 AnsiString
的数据(包括其 StrRec
header,如果需要的话)。您正在尝试 type-cast 未类型化的 Pointer
as-is 直接到 UnicodeString
,这是行不通的。编译器会接受它,但它会假定指针指向 UnicodeString
的有效负载,而不是 AnsiString
的有效负载。因此,您需要 type-cast 指向 PAnsiChar
或 AnsiString
的指针,以便 RTL 知道在分配给 UnicodeString
期间将数据从 ANSI 转换为 Unicode。
我正在使用 Delphi RIO 10.3.3。
当我将 Ansi 字符串作为 const 数组的元素之一传递时,string() 转换对其不起作用。为了让它工作,我必须先将 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;
输出:
代码归功于:How do I build an array of const?
与 UnicodeString
和 WideString
一样,AnsiString
作为指向其数据的 未类型化 指针存储在 TVarRec
中有效载荷。您必须将该指针转换为 AnsiString
(或至少转换为 PAnsiChar
),以便 RTL 正确访问 AnsiString
的数据(包括其 StrRec
header,如果需要的话)。您正在尝试 type-cast 未类型化的 Pointer
as-is 直接到 UnicodeString
,这是行不通的。编译器会接受它,但它会假定指针指向 UnicodeString
的有效负载,而不是 AnsiString
的有效负载。因此,您需要 type-cast 指向 PAnsiChar
或 AnsiString
的指针,以便 RTL 知道在分配给 UnicodeString
期间将数据从 ANSI 转换为 Unicode。