【问题标题】:Firemonkey Windows/iOS compatible codeFiremonkey Windows/iOS 兼容代码
【发布时间】:2016-11-25 10:26:02
【问题描述】:

我正在尝试在 iOS 上运行我用 Firemonkey 编写的应用程序。 我读到了这个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) 获取所有平台的起始索引。 Length 对于所有平台都是相同的(注意 unicode 字符是 Size(Char))。 TBytes 是一个动态字节数组,总是从零开始索引。
  • 为什么你还需要这一切?你不能用TEncoding.UTF8来读写你的字符串吗?
  • 像这样使用low StreamInput.Write(S[Low(s)], Length(S)); ?
  • 是的,但考虑到 unicode 字符串的长度是字节大小的两倍。 Length(S)*SizeOf(Char).
  • 那么Windowsif Length(Result)>0 then Move(s[1], Result[0], Length(s));的这个代码等于这个if Length(Result)>0 then Move(s[Low(s)], Result[0], Length(s)*SizeOf(Char));,第二个可以在Win和iOS上使用吗?同样的情况在这里StreamInput.Write(S[1], Length(S)); = StreamInput.Write(S[Low(S)], Length(S)*SizeOf(Char)); 和这里StreamOutput.Read(S[1], StreamOutput.Size); = StreamOutput.Read(S[[Low(S)], StreamOutput.Size*SizeOf(Char)); ?

标签: ios delphi firemonkey multiplatform


【解决方案1】:

使用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);

【讨论】:

    猜你喜欢
    • 2011-11-08
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多