0

我正在使用移动命令,它用于记录值的一个字节到字符串的转换,但是当我添加更多值时,它会显示垃圾值。这是代码

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;

用法:

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;

我想我必须从哪里开始和停止解码字节数组做一些索引,但我不知道怎么做?谁能解释我如何将字符串存储在字节数组中(当我调试时,我看到有数字和一些 nil 值,如果它们与 nil 值混合在一起,如何从索引中获取字符串?)

4

1 回答 1

0

您在一侧使用移动命令长度 * 2 个字节进行复制,但在另一侧仅长度为字节。如果使用 unicode 字符串,则需要在两边使用 length*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;

但我建议您不要使用指针,而是使用任何类型的序列化,例如内存流。

于 2013-08-12T14:22:40.503 回答