我必须在Android上使用一个使用ansistring的旧单元,ansichar等,以前是在Delphi 2007上构建的,所以我正在努力使它与XE7兼容。
我遇到了几行将空字符串放入AnsiString中,如下所示:FAnsiString := ''
,但现在AnsiString是一个字节数组(FAnsiString : array of Byte
)我得到了消息E2010不兼容的类型。
我试图通过为数组创建一个类型(type TArrayOfByte = array of Byte
)并尝试解析它来解析它:FAnsiString := TArrayOfByte ('')
。
但后来我得到了E2089 Invalid TypeCast。
如何让它正常工作?
下面简化它应该如何工作。 基本上我想要一个返回字节数组的函数。 根据参数,该函数的结果应为空字符串。
{$ifdef android}
type AnsiString = array of Byte;
{$endif}
function FooBar(arguments) : AnsiString
begin
if false then
Result := '';
end;
答案 0 :(得分:1)
Delphi字符串和动态数组在空时都包含nil
指针。所以这个:
var
FAnsiString: AnsiString;
FAnsiString := '';
在幕后有效地做到这一点:
// FAnsiString := '';
if Pointer(FAnsiString) <> nil then
begin
// decrement reference count, if 0 then free memory ...
Pointer(FAnsiString) := nil;
end;
动态数组完全相同。这样:
var
FAnsiString: array of Byte;
FAnsiString := nil;
// Alternatively:
// SetLength(FAnsiString, 0);
有效地做了与幕后AnsiString
清理相同的事情:
// FAnsiString := nil;
if Pointer(FAnsiString) <> nil then
begin
// decrement reference count, if 0 then free memory ...
Pointer(FAnsiString) := nil;
end;
AnsiString
和动态数组都是编译器管理的引用计数类型。它们都自动初始化为nil
。
同样,空字符串的AnsiString
比较:
var
FAnsiString: AnsiString;
if FAnsiString = '' then
...
if FAnsiString <> '' then
实际上只是检查nil
指针:
if Pointer(FAnsiString) = nil then
...
if Pointer(FAnsiString) <> nil then
与动态数组相同,只有在没有类型转换的情况下才能执行此操作:
var
FAnsiString: array of byte;
if FAnsiString = nil then
...
if FAnsiString <> nil then
另一种方法是使用Length()
和SetLength()
,它适用于字符串和动态数组:
var
FAnsiString: AnsiString;
if Length(FAnsiString) = 0 then
...
if Length(FAnsiString) <> 0 then
...
SetLength(FAnsiString, 0);
var
FAnsiString: array of byte;
if Length(FAnsiString) = 0 then
...
if Length(FAnsiString) <> 0 then
...
SetLength(FAnsiString, 0);
当然,在移动编译器中始终有Andreas Hausladen的补丁来启用AnsiString
:
The Return of the Byte-Strings
System.ByteStrings support for XE5 Update 2(以及XE6和XE7)