2013-08-12 2 views
0

move 명령을 사용하여 레코드 값에 대해 1 바이트에서 문자열 변환으로 처리하지만 더 많은 값을 추가하면 가비지 값이 표시됩니다. 내가 시작하고 바이트 배열을 디코딩 중지하는 곳에서 어떤 색인을해야하지만 난 잘 모릅니다 생각레코드를 바이트 배열로 변환하고 델파이에서 값을 추출하는 방법은 무엇입니까?

showmessage(username); 
// displays correct value if recepient_username is not encoded 
showmessage(s); 

procedure TForm1.encodeClick(Sender: TObject); // button click 
var 
    obj2: pprotocol; 
begin 
    new(obj); 
    new(obj2); 
    memo1.Lines.Add('encode click'); 
    obj.username   := 'ahmd'; 
    obj.receipent_username := 'ali'; 

    encode_packet(obj); 
    decode_packet(obj.arr); 

end; 

: 여기 코드는

interface 

type 
    tcommand = (
    cmd_login, 
    cmd_logout, 
    cmd_userinfo, 
    cmd_removeuser, 
    cmd_response 
); 

    tprotocol = record 
    username: string; 
    receipent_username: string; 
    arr: tbytes; 
    case command_id: tcommand of 
     cmd_userinfo: 
     (username2: shortstring; ip: shortstring; port: word); // new info 
     cmd_response: 
     (status: boolean); 
     cmd_removeuser: 
     (username_remove: shortstring); 
    end; 

    pprotocol = ^tprotocol; 

procedure encode_packet(obj: pprotocol); 
procedure decode_packet(arr1: tbytes); 

implementation 

procedure encode_packet(obj: pprotocol); 
begin 
    setlength(obj.arr, length(obj.username) * 2); 
    move(obj.username[1], obj.arr[0], length(obj.username) * 2); 

    setlength(obj.arr, length(obj.receipent_username) * 2); 
    // SetLength(Destination, SourceSize); 
    move(obj.receipent_username[1], obj.arr[1], 
    length(obj.receipent_username) * 2); 
    // problem starts from here 
end; 

procedure decode_packet(arr1: tbytes); 
begin 
    setlength(username, length(arr1)); 
    move(arr1[0], username[1], length(arr1)); 

    setlength(s, length(arr1)); 
    move(arr1[1], s[1], length(arr1)); 
end; 

사용입니까? 아무도 날 바이트 배열에 문자열을 저장하는 방법을 설명 할 수 있습니다 (만약 내가 그렇게 내가 nil 값이 너무 섞여 있다면 하나의 색인 생성에서 문자열을 얻을 수있는 숫자와 일부 무효 값을 보았 디버그)

답변

0

너 복사 명령 길이 * 한쪽에는 2 바이트, 다른쪽에는 길이의 바이트 만 복사하십시오. 유니 코드 문자열을 사용하는 경우 양쪽에 길이 * 2 바이트를 사용해야합니다.

또 다른 문제는 하나의 배열에 하나씩 두 개의 문자열을 복사한다는 것입니다. 두 문자열을 한 배열에 저장하려면 배열 안에 충분한 공간을 할당하고 문자열 길이에 대한 정보를 넣고 두 문자열의 내용을 모두 써야합니다. 예 어떻게 바이트의 1 개 배열에이 문자열을 넣어 :

procedure test; 
var 
    len: integer; 
    buf: array of byte; 
    a,b: string; 
begin 
    a := 'try'; 
    b := 'that'; 

    // save 
    setlength(buf, SizeOf(Char)*(Length(a)+Length(b))+8); 
    len := length(a); 
    move(len, buf[0], 4); 
    len := length(b); 
    move(len, buf[4], 4); 
    move(a[1], buf[8], length(a)*SizeOf(char)); 
    move(b[1], buf[8+length(a)*SizeOf(char)], length(a)*SizeOf(char)); 

    // restore 
    a := ''; 
    b := ''; 
    move(buf[0], len, 4); 
    setlength(a, len); 
    move(buf[4], len, 4); 
    setlength(b, len); 
    move(buf[8], a[1], length(a)*SizeOf(char)); 
    move(buf[8+length(a)*SizeOf(char)], b[1], length(a)*SizeOf(char)); 
end; 

하지만 난 당신이 포인터를 재생하고 예를 메모리 스트림을 위해, 대신 직렬화의 어떤 종류를 사용하지 않는 것이 좋습니다.