简体   繁体   English

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

[英]Delphi XE7 Android Record with String Element won't compile

In Delphi FMX XE7, Win32, I have a record type: 在Delphi FMX XE7,Win32中,我有一个记录类型:

type TSettingsRec = record
  SessionTimeOut: Word;
  EventString: String[50];
end;

When I change the Target to Android, I get a compiler error: 当我将目标更改为Android时,我收到编译错误:

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

I need to define the length[50] of the EventString element because the TRecord is actually being read from a database (Firebird) which was written to the database by a Delphi 7 program using Bin2Hex (for a reason known only to the author of that program): 我需要定义EventString元素的长度[50],因为TRecord实际上是从数据库(Firebird)中读取的,该数据库是由Delphi 7程序使用Bin2Hex写入数据库的(原因只有作者才知道)程序):

var
  rec: TSettingsRec;
  settings: string;

SetLength(settings, SizeOf(rec)*2);
BinToHex(@rec, @settings[1]), SizeOf(rec));

This I decode effectively in using XE7 (win32) using: 我使用XE7(win32)有效解码:

var
  rec: TSettingsRec;
  settings: String;

SetLength(settings, SizeOf(rec) * 2);
System.Classes.HexToBin(Pchar(settings), @rec, SizeOf(rec));

But this doesn't work, when I compile for Android. 但是,当我为Android编译时,这不起作用。 So how do I specify the length [50] of the EventString on the Android platform? 那么如何在Android平台上指定EventString的长度[50]呢?

You cannot use short strings on the mobile compilers. 您不能在移动编译器上使用短字符串。 You'll need to re-think the code. 你需要重新思考代码。 Perhaps like this: 也许是这样的:

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;

This replicates the memory layout of the legacy short string. 这复制了传统短字符串的内存布局。 Which is a single byte containing the string length, followed by an array of length 50, of ANSI encoded text containing the payload. 这是包含字符串长度的单个字节,后跟长度为50的数组,包含有效负载的ANSI编码文本。 The record wraps the legacy layout with more natural properties, which make the type more readily usable. 该记录使用更自然的属性包装旧版布局,这使得类型更容易使用。

Of course we still need to write those properties. 当然,我们仍然需要编写这些属性。 Like this: 像这样:

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;

This will work on Windows, but not on mobile compilers because TEncoding.ANSI has no meaning. 这将适用于Windows,但不适用于移动编译器,因为TEncoding.ANSI没有任何意义。 So you'll need to create an encoding with the desired code page. 因此,您需要使用所需的代码页创建编码。 For instance: 例如:

Encoding := TEncoding.Create(1252);

Do note that I've not even compiled this code, so it may have some wrinkles. 请注意,我甚至没有编译此代码,因此它可能有一些皱纹。 But I think the concept shown here is the cleanest way to move your code forward. 但我认为这里显示的概念是最简单的代码转发方式。 I'll leave you to work out the appropriate details for your setting. 我会让你为你的设置制定适当的细节。

String[50] is not supported on mobile platforms. 移动平台不支持String[50] That is a legacy data type known as a ShortString , consisting of 51 bytes of data, where the first byte is the length of the string and the next 50 bytes are 8-bit characters that define the string value. 这是一种称为ShortString的遗留数据类型,由51个字节的数据组成,其中第一个字节是字符串的长度,接下来的50个字节是定义字符串值的8位字符。

The equivalent definition would be array[0..50] of byte , where the first byte defines the length of the actual data. 等效定义是array[0..50] of byte ,其中第一个字节定义实际数据的长度。 byte is used because the mobile platforms do not support AnsiChar (without a 3rd party patch). byte是因为移动平台不支持AnsiChar (没有第三方补丁)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM