Halaman

Kamis, 25 Agustus 2011

Delphi : Variable Parameters, Packed Records

Variable Parameters
taken from www.chami.com
//
// FunctionWithVarArgs()
//
// skeleton for a function that
// can accept vairable number of
// multi-type variables
//
// here are some examples on how
// to call this function:
//
// FunctionWithVarArgs(
//   [ 1, True, 3, '5', '0' ] );
//
// FunctionWithVarArgs(
//   [ 'one', 5 ] );
//
// FunctionWithVarArgs( [] );
//
procedure FunctionWithVarArgs(
  const ArgsList : array of const );
var
  ArgsListTyped :
    array[0..$FFF0 div SizeOf(TVarRec)]
      of TVarRec absolute ArgsList;
  n         : integer;
begin
  for n := Low( ArgsList ) to
           High( ArgsList ) do
  begin
    with ArgsListTyped[ n ] do
    begin
      case VType of
        vtInteger   : begin
          {handle VInteger here}      end;
        vtBoolean   : begin
          {handle VBoolean here}      end;
        vtChar      : begin
          {handle VChar here}         end;
        vtExtended  : begin
          {handle VExtended here}     end;
        vtString    : begin
          {handle VString here}       end;
        vtPointer   : begin
          {handle VPointer here}      end;
        vtPChar     : begin
          {handle VPChar here}        end;
        vtObject    : begin
          {handle VObject here}       end;
        vtClass     : begin
          {handle VClass here}        end;
        vtWideChar  : begin
          {handle VWideChar here}     end;
        vtPWideChar : begin
          {handle VPWideChar here}    end;
        vtAnsiString: begin
          {handle VAnsiString here}   end;
        vtCurrency  : begin
          {handle VCurrency here}     end;
        vtVariant   : begin
          {handle VVariant here}      end;
        else          begin
          {handle unknown type here} end;
      end;
    end;
  end;
end;
Packed Records
Packed records is a way to align Delphi records. Delphi variables usually aligned at 2, 4, or 8 byte to optimize access, to make things clear, take a look at following code (taken from delphibasic.co.uk)
type
  // Declare an unpacked record
  TDefaultRecord = Record
    name1   : string[4];
    floater : single;
    name2   : char;
    int     : Integer;
  end;

  // Declare a packed record
  TPackedRecord = Packed Record
    name1   : string[4];
    floater : single;
    name2   : char;
    int     : Integer;
  end;

var
  defaultRec : TDefaultRecord;
  packedRec  : TPackedRecord;

begin
  ShowMessage('Default record size = '+IntToStr(SizeOf(defaultRec)));
  ShowMessage('Packed record size = '+IntToStr(SizeOf(packedRec)));
end;
there is more advanced usage for the record type of delphi, such as this one :
type 
   TRect = packed record
     case Integer of
       0: (Left, Top, Right, Bottom: Integer);
       1: (TopLeft, BottomRight: TPoint);
   end; 
TRect.TopLeft will map to the TRect.Left and TRect.Top, TRect.BottomRight will map to the TRect.Right and TRect.Bottom, anoher usage would be like this one :
type
   // Declare a fruit record using case to choose the
   // diameter of a round fruit, or length and height ohterwise.
   TFruit = Record
     name : string[20];
     Case isRound : Boolean of // Choose how to map the next section
       True  :
         (diameter : Single);  // Maps to same storage as length
       False :
         (length   : Single;   // Maps to same storage as diameter
          width    : Single);
   end;
when isRound is true, you could define 1 more variable, and that is the diameter:Single, and if isRound is false, you could define 2 more variable, that is length, and width

Tidak ada komentar:

Posting Komentar