1

私は記録を持っています

type
  Treply = record
    c: integer;
    b: integer;
    a: int64;
  end;

UDP プロトコルを使用してサーバーからデータを受信しました。データは「ビッグ エンディアン」です。

udp : TIdUDPClient;
received_data : TIdBytes;

udp.ReceiveBuffer(received_data);

received_data を通常の int/int/int64 にデコードし、それをレコード Treply に入れる方法は?

ありがとう

4

1 に答える 1

2

この場合、レコードにはパディングがないため、バッファの内容をレコードにコピーするだけです。

var
  Reply: TReply;
....
Move(received_data[0], Reply, SizeOf(Reply));

次に、ネットワーク バイト オーダーからホスト バイト オーダーに変換する必要があります。そして、あなたは前の質問からそれを行う方法を知っています.

レコードのパディング/アラインメントの問題に巻き込まれないようにするために、ブリットしたレコードをワイヤにパックすることをお勧めします。

TReply = packed record
  ....

received_dataまた、 を呼び出す前に、 に適切な量の情報が含まれていることを確認する必要がありますMove

個人的には、Indy の関数を使用してホストとネットワークのバイト順を変換することで、レコードをもう少し強力なものにすることができます。

type
  TReply = packed record
    c: integer;
    b: integer;
    a: int64;
    function HostToNetwork: TReply;
    function NetworkToHost: TReply;
  end;

function TReply.HostToNetwork: TReply;
begin
  Result.c := GStack.HostToNetwork(Cardinal(c));
  Result.b := GStack.HostToNetwork(Cardinal(b));      
  Result.a := GStack.HostToNetwork(a);
end;

function TReply.NetworkToHost: TReply;
begin
  Result.c := GStack.NetworkToHost(Cardinal(c));
  Result.b := GStack.NetworkToHost(Cardinal(b));      
  Result.a := GStack.NetworkToHost(a);
end;

すべてをまとめると、逆シリアル化コードは次のようになります。

if Length(received_data)<>SizeOf(Reply) then
  raise SomeException.Create('...');
Move(received_data[0], Reply, SizeOf(Reply));
Reply := Reply.NetworkToHost;
于 2012-11-22T20:49:50.183 に答える