AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Record Größe zur Laufzeit bestimmen

Ein Thema von brechi · begonnen am 18. Apr 2008 · letzter Beitrag vom 21. Apr 2008
 
Benutzerbild von nicodex
nicodex

Registriert seit: 2. Jan 2008
Ort: Darmstadt
286 Beiträge
 
Delphi 2007 Professional
 
#7

Re: Record Größe zur Laufzeit bestimmen

  Alt 21. Apr 2008, 08:46
Ein wenig Pseudo-Code:
Delphi-Quellcode:
{$ALIGN Alignment}
type
  TFoo = record
    b : Byte; // $00
  //x1: array [0..6] of Byte; // $01 Align(Min(Alignment, SizeOf(a)))
    a : Extended; // $08
  //x2: array [0..1] of Byte; // $12 Align(Min(Alignment, SizeOf(i)))
    i : Integer; // $14
  //x3: array [ ] of Byte // $18 Align(Min(Alignment, SizeOf(MaxMember))
  end; // ($18)
Noch ein Edit um Missverständnissen vorzubeugen
SizeOf(...) in den Kommentaren ist das 'Alignment, welches für das Strukturmitglied benötigt wird'. SizeOf() ist insofern 'inkorrekt', da das Alignment eines strukturierten Typs das Alignment des 'größten Mitglieds' ist.
Beispiel:Arr: array [0..1] of Word; Die benötigte Ausrichtung für Arr ist die Größe eines Elements - nicht SizeOf(Arr)!
Delphi-Quellcode:
Bar: record
  A: Word; // 'größte erforderliche Ausrichtung' in Bar
  B: Byte;
//x: Byte;
end;
SizeOf(Bar) ist 4. Die Ausrichtung für Bar selbst ist 2 (Bar.A erfordert eine Ausrichtung der Struktur an 2 Bytes).

Lösungsansatz für o.g. Problem:
Delphi-Quellcode:
type
  PXType = ^TXType;
  TXType = (
    xByte,
    xWord,
    xInteger,
    xDouble,
    xExtended
  );

const
  XTypeSize: array [TXType] of Cardinal = (
    SizeOf(Byte), // xByte
    SizeOf(Word), // xWord
    SizeOf(Integer), // xInteger
    SizeOf(Double), // xDouble
    SizeOf(Extended) // xExtended
  );

type
  // Dummy type to automatically detect the default alignment
  TAlignmentDetection = record
    A: Byte;
    B: Int64;
  end;

function GetRecordAlignment(const ATypes: array of TXType; AAlignment: Cardinal
  ): Cardinal;
var
  Index: Integer;
  Align: Cardinal;
begin
  if AAlignment < 1 then
    AAlignment := SizeOf(TAlignmentDetection) - SizeOf(Int64);
  Result := 0;
  for Index := Low(ATypes) to High(ATypes) do
  begin
    Align := XTypeSize[ATypes[Index]];
    if Align > AAlignment then
      Align := AAlignment;
    if Align > Result then
      Result := Align;
  end;
end;

function GetRecordSize(const ATypes: array of TXType; AAlignment: Cardinal
  ): Cardinal;
var
  ResultAlign: Cardinal;
  Index: Integer;
  XSize: Cardinal;
  Align: Cardinal;
  Spare: Cardinal;
begin
  if AAlignment < 1 then
    AAlignment := SizeOf(TAlignmentDetection) - SizeOf(Int64);
  Result := 0;
  ResultAlign := 0;
  for Index := Low(ATypes) to High(ATypes) do
  begin
    XSize := XTypeSize[ATypes[Index]];
    if XSize > 1 then
    begin
      Align := XSize;
      if Align > AAlignment then
        Align := AAlignment;
      if Align > ResultAlign then
        ResultAlign := Align;
      Spare := Align - (Result mod Align);
      if Spare < Align then
        Inc(Result, Spare);
    end;
    Inc(Result, XSize);
  end;
  if ResultAlign > 1 then
  begin
    Spare := ResultAlign - (Result mod ResultAlign);
    if Spare < ResultAlign then
      Inc(Result, Spare);
  end;
end;
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:52 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz