私はデータ構造を持っています:
data = array of integer;
私はそれを
source = array of byte;
と
data[x] := Source[offset] or (Source[offset + 1] shl 8) or
(Source[offset + 2] shl 16) or (Source[offset + 3] shl 24);
これらのブロックを処理した後、それらを「バイト」に戻す必要があります。
何か案が?
こんな感じですか?
var
i: integer;
b1, b2, b3, b4: byte;
begin
b1 := byte(i);
b2 := byte(i shr 8);
b3 := byte(i shr 16);
b4 := byte(i shr 24);
たとえば、
procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
b1, b2, b3, b4: byte;
begin
i := $AABBCCDD;
b1 := byte(i);
b2 := byte(i shr 8);
b3 := byte(i shr 16);
b4 := byte(i shr 24);
ShowMessage(IntToHex(b1, 2));
ShowMessage(IntToHex(b2, 2));
ShowMessage(IntToHex(b3, 2));
ShowMessage(IntToHex(b4, 2));
end;
これは、Move を使用してワンライナーで実行できます。
Move(source[0], dest[0], Length(source)*SizeOf(source[0]));
ネットワーク/ホストのバイト順変換を実行する必要がある場合は、. の後に整数配列を実行できますMove。
反対方向では、すべて逆に行います。
バイト オーダーの問題がなければ、実際にはバイト配列に変換する必要はまったくないかもしれません。整数配列をそのまま使用できる可能性があります。バイト順の問題がなければ、バイト配列と整数配列のメモリ レイアウトは同じであることに注意してください (これが で blit できる理由ですMove)。
うーん...移動を使用した回答とシフトを使用した回答が表示されますが、単純なキャストはどうですか?:
var
I: Integer;
B: array[0..3] of Byte;
begin
// from bytes to integer:
I := PInteger(@B)^;
// from integer to bytes:
PInteger(@B)^ := I;
またはあなたの配列で:
data[i] := PInteger(@source[offset])^;
およびその逆:
// get low byte
source[offset] := PByte(@data[i])^; // or := PByte(@data[i])[0];
// get second byte
secondByte := PByte(@data[i])[1]; // or := (PByte(@data[i]) + 1)^;
また
PInteger(@source[offset])^ := data[i];
ご覧のとおり、ポインターにキャストすることで、長い道のりを歩むことができます。これは実際にはポインターを取りません。コンパイラーはアイテムに直接アクセスするのに十分賢いです。
コメントしたように、バイトと整数の両方としてアクセスするためにデータを移動する必要はありません。
元のバイト配列は、型キャストによって整数の配列としてアクセスできます。
type
TArrayInteger = array of Integer;
...
for i := 0 to Pred(Length(source)) div SizeOf(Integer) do
WriteLn(TArrayInteger(source)[i]);
多くの場合、これらの型キャストをクラスに隠します。XE3 では、文字列、バイト、整数などの単純な型のクラス ヘルパーを宣言する可能性があります。たとえば、TStringHelper を参照してください。同じことが単純型の配列にも当てはまります。
レコード ヘルパーを使用した例を次に示します。
type
TArrayByte = array of Byte;
TArrayInteger = array of Integer;
TArrayByteHelper = record helper for TArrayByte
private
function GetInteger(index : Integer) : Integer;
procedure SetInteger(index : Integer; value : Integer);
public
property AsInteger[index : Integer] : Integer read GetInteger write SetInteger;
end;
function TArrayByteHelper.GetInteger(index: Integer): Integer;
begin
Result := TArrayInteger(Self)[index];
end;
procedure TArrayByteHelper.SetInteger(index: Integer; value: Integer);
begin
TArrayInteger(Self)[index] := value;
end;
次のように使用します。
Var
source : TArrayByte;
i : Integer;
begin
SetLength(source,8);
for i := 0 to 7 do
source[i] := i;
for i := 0 to 1 do
WriteLn(Format('%8.8X',[source.AsInteger[i]]));
ReadLn;
end.