AGB  ·  Datenschutz  ·  Impressum  







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

Delphi-Equivalent zur C-union

Ein Thema von oXmoX · begonnen am 21. Jun 2005 · letzter Beitrag vom 22. Jun 2005
 
NicoDE
(Gast)

n/a Beiträge
 
#9

Re: Delphi-Equivalent zur C-union

  Alt 22. Jun 2005, 11:36
Ein C-struct entspricht einem Delphi-record; soweit dürfte das klar sein.

Nehmen wir mal die C-Union:
Code:
//...
    union
    {
        long   foo;
        char   bar;
    };
Unions werden verwendet um die gleiche Variable (Speicheradresse) mit verschiedenen Namen ansprechen zu können. '.foo' und '.bar' sind also an der gleichen Stelle (und eigentlich eine Variable). In der Variable steht entweder ein 'Foo'-Wert oder ein 'Bar'-Wert (die Unterscheidung zwischen den beiden Bedeutungen einer Variable muss irgendwo in der Dokumentation stehen...). Verwendet wird das ganze meist um Speicherplatz zu sparen.

In Delphi Language nennt man dies den 'varianten Teil einer Struktur'; und so sieht das ganze so aus:
Delphi-Quellcode:
//...
  case Integer of
    0: (
      foo: Longint;
    );
    1: (
      bar: AnsiChar;
    );
{ end; }
Integer als Aufzählungstyp ist frei gewählt. Die einzelnen Varianten der Struktur sind in Delphi-Language deutlicher zu erkennen als in C. Man muss sich nur an das 'case'-Konstrukt in Strukturen gewöhnen.

Warum ist nun das Ende des varianten Teils der Struktur auskommentiert?
Nun, die Delphi Language unterstützt variante Teile nur als letzten Teil einer Struktur. Es können also keine weiteren Variablen folgen!

Was soll man dann aber mit folgenden C-Konstrukt anstellen?
Code:
//...
    union
    {
        long   foo;
        char   bar;
    };
    int alc;
Da in der Delphi-Language keine weiteren Variablen folgen können, müssen wir die folgenden Strukturmitglieder an den größten Teil der varianten Struktur anhängen. Da .foo größer ist als .bar, müssen wir beide vertauschen. Das ganze sieht dann so aus:
Delphi-Quellcode:
//...
  case Integer of
    1: (
      bar: AnsiChar;
    );
    0: (
      foo: Longint;
{ end; }
      alc: Integer;
    );
oder anders formatiert:
Delphi-Quellcode:
//...
  case Integer of
    1: (bar: AnsiChar);
    0: (foo: Longint;
  alc: Integer);
Nun haben wir also einen Trick gefunden, um Strukturmitglieder nach einem varianten Teil zu deklarieren.


Dies kann natürlich wieder ein varianter Teil sein, also in der oben gestellten Frage:
Delphi-Quellcode:
//...
  case Integer of
    0: (
      rows : Integer;
    );
    1: (
      height: Integer;
{ end; }
      case Integer of
        0: (
          cols : Integer;
        );
        1: (
          width : Integer;
        );
    );
oder anders formatiert:
Delphi-Quellcode:
//...
  case Integer of
    0: (rows : Integer);
    1: (height: Integer;
  case Integer of
    0: (cols : Integer);
    1: (width : Integer))
  end;
(das Semikolon fehlt nach dem letzten Teil eines Blocks - Geschmacksfrage, aber gültiges Pascal)


Kommen wir am Ende zu benannten C-Unions:
Code:
//...
    union
    {
        long   foo;
        char   bar;
    } dat;
Die Variablen werden nun mit dat.foo und dat.bar angesprochen. Das entspricht der Funktionalität eines Delphi-record.
Also übersetzen wir die benannte Union mit einem inline-record:
Delphi-Quellcode:
//...
  dat: record
    case Integer of
      0: (
        foo: Longint;
      );
      1: (
        bar: AnsiChar;
      );
  { end; }
  end;

Wenn wir nun unser gewonnenes Wissen bündeln und die Macht mit uns ist, dann können wir den oben gefragten C-Code mit folgendem Übersetzen:
Delphi-Quellcode:
type
  CvMat = record
    type_: Integer;
    step: Integer;
    refcount: PInteger;
    data: record
      case Integer of
        0: (
          ptr: PByte;
        );
        1: (
          s: PSmallInt;
        );
        2: (
          i: PInteger;
        );
        3: (
          fl: PSingle;
        );
        4: (
          db: PDouble;
        );
    { end; }
    end;
    case Integer of
      0: (
        rows: Integer;
      );
      1: (
        height: Integer;
  { end; }
        case Integer of
          0: (
            cols: Integer;
          );
          1: (
            width: Integer;
          );
      { end; }
      );
  end;
oder anders formatiert:
Delphi-Quellcode:
type
  CvMat = record
    type_ : Integer;
    step : Integer;
    refcount : PInteger;
    data : record
      case Integer of
        0: (ptr : PByte);
        1: (s : PSmallInt);
        2: (i : PInteger);
        3: (fl : PSingle);
        4: (db : PDouble)
    end;
    case Integer of
      0: (rows : Integer);
      1: (height: Integer;
    case Integer of
      0: (cols : Integer);
      1: (width : Integer))
  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 01:49 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 by Thomas Breitkreuz