2016-11-25 3 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

사용'저 (들)'모든 플랫폼의 시작 인덱스를 얻을 수 있습니다. 'Length'는 모든 플랫폼에서 동일합니다 (유니 코드 문자는 Size (Char)입니다). 'TBytes'는 동적 바이트 배열이며, 항상 0부터 시작합니다. –

+0

왜이 모든 것이 필요합니까? 문자열을 읽고 쓰는데'TEncoding.UTF8'을 사용할 수 없습니까? –

+0

'StreamInput.Write (S [Low (s)], Length (S));와 같이 낮음을 사용하십시오. – 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 문자열로 유니 코드 문자열 DataText 변환합니다.

TBytes은 동적 바이트 배열입니다. 모든 동적 배열은 0을 기준으로합니다. System.UTF8Encode를 사용

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

가 UTF8 바이트 배열에 유니 코드 문자열로 변환하는 다른 방법입니다

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