带字符串元素的Delphi XE7 Android记录无法编译

nol*_*ker 2 delphi android firemonkey delphi-xe7

在Delphi FMX XE7,Win32中,我有一个记录类型:

type TSettingsRec = record
  SessionTimeOut: Word;
  EventString: String[50];
end;
Run Code Online (Sandbox Code Playgroud)

当我将目标更改为Android时,我收到编译错误:

[DCC错误] MainForm.pas(45):E2029';' 预期,但'''发现

我需要定义EventString元素的长度[50],因为TRecord实际上是从数据库(Firebird)读取的,该数据库是由Delphi 7程序使用Bin2Hex写入数据库的(原因只有作者才知道)程序):

var
  rec: TSettingsRec;
  settings: string;

SetLength(settings, SizeOf(rec)*2);
BinToHex(@rec, @settings[1]), SizeOf(rec));
Run Code Online (Sandbox Code Playgroud)

我使用XE7(win32)有效解码:

var
  rec: TSettingsRec;
  settings: String;

SetLength(settings, SizeOf(rec) * 2);
System.Classes.HexToBin(Pchar(settings), @rec, SizeOf(rec));
Run Code Online (Sandbox Code Playgroud)

但是,当我为Android编译时,这不起作用.那么如何在Android平台上指定EventString的长度[50]呢?

Dav*_*nan 6

您不能在移动编译器上使用短字符串.你需要重新思考代码.也许是这样的:

type
  TSettingsRec = record
  private
    FSessionTimeOut: Word;
    FEventStringLength: Byte;
    FEventString: array [0..49] of Byte; // ANSI encoded
    function GetEventString: string;
    procedure SetEventString(const Value: string);
  public
    property SessionTimeOut: Word read FSessionTimeOut write FSessionTimeOut;
    property EventString: string read GetEventString write SetEventString;
  end;
Run Code Online (Sandbox Code Playgroud)

这复制了传统短字符串的内存布局.这是包含字符串长度的单个字节,后跟长度为50的数组,包含有效负载的ANSI编码文本.该记录使用更自然的属性包装旧版布局,这使得类型更容易使用.

当然,我们仍然需要编写这些属性.像这样:

function TSettingsRec.GetEventString: string;
var
  Bytes: TBytes;
begin
  SetLength(Bytes, Min(FEventStringLength, Length(FEventString)));
  Move(FEventString, Pointer(Bytes)^, Length(Bytes));
  Result := TEncoding.ANSI.GetString(Bytes);
end;

procedure TSettingsRec.SetEventString(const Value: string);
var
  Bytes: TBytes;
begin
  Bytes := TEncoding.ANSI.GetBytes(Value);
  FEventStringLength := Min(Length(Bytes), Length(FEventString));
  Move(Pointer(Bytes)^, FEventString, FEventStringLength);
end;
Run Code Online (Sandbox Code Playgroud)

这将适用于Windows,但不适用于移动编译器,因为TEncoding.ANSI没有任何意义.因此,您需要使用所需的代码页创建编码.例如:

Encoding := TEncoding.Create(1252);
Run Code Online (Sandbox Code Playgroud)

请注意,我甚至没有编译此代码,因此它可能有一些皱纹.但我认为这里显示的概念是最简单的代码转发方式.我会让你为你的设置制定适当的细节.