Thursday, October 8, 2009

Pointer to Byte array

Did you ever needed to get a variable as an array of byte? I mean you should know that the smallest value with which you can work is a byte(you can play with bits also but normally you don't) so a Word is represented on 2 Bytes, a Integer/Cardinal on 4 bytes, Double 7 Bytes, Int64 8 Bytes(se Delphi help for more info)...
First we need to declare 2 types
type
    (* declare a dynamic array of Byte type *)
    TypeByteArray = array of Byte;
    (* declare a dynamic array of PByte type *)
    TypePtrByteArray = array of PByte;
and now we need the utility functions which translates a pointer to an array of bytes, these utility functions take 2 parameters, the first parameter is the pointer to a variable(the @ operator can be used) and the second parameter takes the size in bytes of the variable, for instance if we pass a Integer value then the parameters should look like so: (@myInteger, 4), if the size of the passed parameter is 4 then you do not need to pass the second parameter, because it is declared as a constant of 4 bytes
function PointerToByteArray(
         (* the pointer to variable,
            @ operator can be used *)
         Value: Pointer;
         (* the size in bytes of the
            variable:
            Byte = 1
            Word = 2
            Integer/Cardinal = 4
            Double = 7
            Int64 = 8 *)
         const SizeInBytes: Cardinal = 4
         ): TypeByteArray;
var Address, (* store the address locally *)
    index: integer; (* for loop *)
begin
     (* get the pointer address *)
     Address := Integer(Value);
     (* set the length of the array *)
     SetLength(Result, SizeInBytes);
     (* loop to get all bytes *)
     for index := 0 to SizeInBytes do
         (* convert the address + index to a PByte pointer,
            use the ^ operator so compiler knows that
            we refer to the pointer's value *)
         Result[index] := PByte(Ptr(Address + Index))^;
end;

function PointerToPtrByteArray
         (* the pointer to variable,
            @ operator can be used *)
         (Value: Pointer;
         (* the size in bytes of the
            variable:
            Byte = 1
            Word = 2
            Integer/Cardinal = 4
            Double = 7
            Int64 = 8 *)
         const SizeinBytes: Cardinal = 4): TypePtrByteArray;
var Address, (* store the address locally *)
    index: integer; (* for loop *)
begin
     (* get the pointer address *)
     Address := Integer(Value);
     (* set the length of the array *)
     SetLength(Result, SizeInBytes);
     (* loop to get all bytes *)
     for index := 0 to SizeInBytes do
         (* convert the address + index to a PByte pointer *)
         Result[index] := Ptr(Address + Index);
end;
An example of getting an integer value as an array of bytes and display each byte value
procedure TForm1.Button1Click(Sender: TObject);
const
     CH_CR = #13; (* da' return char *)
var
   value: Integer;
   s: String;
   arr: TypeByteArray;
   index: integer;
begin
     (* assign a value to "Value" variable *)
     value := 2009;
     (* store the bytes on our dynamic array *)
     arr := PointerToByteArray(@Value);
     (* loop to get each byte from array *)
     for index := 0 to 3 do
         s := s + CH_CR + IntToStr(arr[index]);
     (* display array values in a message *)
     ShowMessage(s);
     (* resize the array to 0 elements *)
     SetLength(arr, 0);
     (* nil it *)
     arr := nil;
end;

No comments:

Post a Comment

Blogroll(General programming and Delphi feeds)