Delphi XE3 -> Integer to array of Bytes

后端 未结 5 1308
野趣味
野趣味 2021-01-02 22:52

I have a data structure:

data = array of integer;

I have filled it from an

source = array of byte;

with

相关标签:
5条回答
  • 2021-01-02 23:07

    Hmmm... I see an answer using Move and one using shifts, but what about a simple cast?:

    var
      I: Integer;
      B: array[0..3] of Byte;
    begin
      // from bytes to integer:
      I := PInteger(@B)^;
      // from integer to bytes:
      PInteger(@B)^ := I;
    

    Or with your arrays:

    data[i] := PInteger(@source[offset])^;
    

    and vice versa:

    // 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)^;
    

    or

    PInteger(@source[offset])^ := data[i];
    

    As you see, you can get a long way by casting to pointers. This does not actually take the pointer, the compiler is clever enough to access the items directly.

    0 讨论(0)
  • 2021-01-02 23:22

    As commented, you do not need to move the data to access it as both byte and integer.

    Your original array of byte could be accessed as an array of integer by type casting.

    type
      TArrayInteger = array of Integer;
    ...
    for i := 0 to Pred(Length(source)) div SizeOf(Integer) do
      WriteLn(TArrayInteger(source)[i]);
    

    Often I hide these type casts in a class. In XE3 there is possibility to declare class helpers for simple types, like string,byte,integers, etc. See TStringHelper for example. The same goes for array of simple types.

    Here is an example using a record helper:

    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;
    

    Use it like this:

    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.
    
    0 讨论(0)
  • 2021-01-02 23:26

    You mean like this?

    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);
    

    Try, for instance,

    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;
    
    0 讨论(0)
  • 2021-01-02 23:28

    To build this as a function:

    Type TBytes = array of byte;
    
    function InttoBytes(const int: Integer): TBytes;
    begin
      result[0]:= int and $FF;
      result[1]:= (int shr 8) and $FF;
      result[2]:= (int shr 16) and $FF;
    end;
    
    0 讨论(0)
  • 2021-01-02 23:30

    You can do this in a one-liner using Move.

    Move(source[0], dest[0], Length(source)*SizeOf(source[0]));
    

    If you need to perform a network/host byte order transformation, then you can run across the integer array after the Move.

    In the opposite direction you do it all in reverse.

    If you haven't got byte order issues then you might not actually need to convert to a byte array at all. It's possible that you can use the integer array as is. Remember that, without byte order issues, the memory layout of the byte and integer arrays are the same (which is why you are able to blit with Move).

    0 讨论(0)
提交回复
热议问题