Firemonkey Windows/iOS 兼容代码

Firemonkey Windows/iOS compatible code

我正尝试 运行 我的应用程序,用 Firemonkey 编写,在 iOS 上。 我读过这个 http://docwiki.embarcadero.com/RADStudio/Seattle/en/Migrating_Delphi_Code_to_Mobile_from_Desktop 但我的意思是它不是全部 :-/

我有这个程序

procedure generateData(Var OutVar:String;DataText:String);
var
  S: TBytes;
  StreamInput, StreamOutput: TMemoryStream;
  // String to TBytes
  function UTF8Bytes(const s: UTF8String): TBytes;
  begin
    SetLength(Result, Length(s));
    {$IFDEF IOS} // iOS strings are 0 based but hor about retyped ???
    // this ?
    if Length(Result)>0 then Move(s[0], Result[0], Length(s)-1);
    // or this ?
    //if Length(Result)>0 then Move(s[0], Result[0], Length(s));
    // or this ?
    //if Length(Result)>0 then Move(s[1], Result[0], Length(s));
    {$ELSE} // Win strings are 1 based
    if Length(Result)>0 then Move(s[1], Result[0], Length(s));
    {$ENDIF}
  end;
begin
  StreamInput := TMemoryStream.Create;
  StreamOutput := TMemoryStream.Create;
  S := UTF8Bytes(DataText);

  {$IFDEF IOS} // What about TBytes? They are different too ?
  // this ?
  //StreamInput.Write(S[0], Length(S)-1);
  // or this ?
  StreamInput.Write(S[0], Length(S));
  {$ELSE}
  StreamInput.Write(S[1], Length(S));
  {$ENDIF}

  StreamInput.Position := 0;

  MyCryptoStreamFunction(StreamInput, StreamOutput);
  StreamOutput.Position := 0;

  SetLength(S, StreamOutput.Size);
  {$IFDEF IOS}
  // this ?
  StreamOutput.Read(S[0], StreamOutput.Size);
  // or this ?
  //StreamOutput.Read(S[0], StreamOutput.Size-1);
  // this will raise exception and kill app
  //StreamOutput.Read(S[1], StreamOutput.Size);
  {$ELSE}
  StreamOutput.Read(S[1], StreamOutput.Size);
  {$ENDIF}
  OutVar := StringReplace(EncodeBase64(S,Length(S)), sLineBreak, '',[rfReplaceAll]);
end;

在 windows 上正常工作,但在 ios 上此代码 StreamOutput.Read(S[1], StreamOutput.Size); 引发异常并终止我的应用程序。

谁能帮忙看看 {$IFDEF IOS} 中的代码变体与 {ELSE} 中的代码是否相等 通过它们的功能?

使用Low(s)获取所有平台的字符串的第一个索引:

// utf8 string to TBytes
function UTF8Bytes(const s: UTF8String): TBytes;
begin
  SetLength(Result, Length(s));
  if (Length(s) > 0) then
    Move(s[Low(s)],Result[0],Length(s));
end;

S := UTF8Bytes(DataText);在进入函数前将unicode字符串DataText隐式转换为utf8字符串。

TBytes 是动态字节数组。所有动态数组都是从零开始的。

StreamInput.Write(S[0],Length(S));

使用 System.UTF8Encode 是将 unicode 字符串转换为 utf8 字节数组的另一种方法:

procedure UTF8Encode(const US: UnicodeString; var B: array of Byte);