2016-11-25 6 views
0

iOS上でFiremonkeyで書かれた自分のアプリケーションを実行しようとしています。 私はこのhttp://docwiki.embarcadero.com/RADStudio/Seattle/en/Migrating_Delphi_Code_to_Mobile_from_Desktopを読みましたが、私はそれがすべてではないことを意味: -/Firemonkey Windows/iOS互換コード

私は窓に

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; 

が正常に動作しますが、iOSのこのコードStreamOutput.Read(S[1], StreamOutput.Size);昇給の例外をし、私のアプリを殺すこの手順を持っています。

{$ IFDEF IOS}のコードの亜種が{ELSE} のコードと同等の機能を持つことは誰でも助けてください。

+1

'ロー(s)は'すべてのプラットフォームの開始インデックスを取得するために使用します。 'Length'はすべてのプラットフォームで同じです(Unicode文字はSize(Char)です)。 'TBytes'は常にゼロからインデックスされた動的バイト配列です。 –

+0

どうしてこのすべてが必要なのですか?文字列を読み書きするのに 'TEncoding.UTF8'を使用できませんか? –

+0

この 'StreamInput.Write(S [Low(s)]、Length(S));のようにlowを使用します。 – Andy

答えて

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);は、暗黙的機能に入る前にUTF8文字列にUnicode文字列DataTextを変換します。

TBytesは動的バイト配列です。すべての動的配列はゼロベースです。 System.UTF8Encodeを使用して

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

のutf8バイト配列にUnicode文字列を変換する別の方法です:

procedure UTF8Encode(const US: UnicodeString; var B: array of Byte); 
関連する問題