Board index » delphi » Delphi Equivalent of 'C' Union Variable Declaration?

Delphi Equivalent of 'C' Union Variable Declaration?

Brian Hoffman <bhoff...@discover.net> wrote in article
<33F7FAF5.1...@discover.net>...

Quote
> Help!  Is there any way to create a Delphi variable that is
> equivalent to the following 'C' union variable declaration?
> Here it is:

>         typedef struct _ls_var
>         {
>             int     type;

>             union {
>                 double      number;
>                 const char *string;
>                 double      vector[3];
>             } data;
>         } LS_VAR;

Brian,

What you need is a "variant record," which you should not
confuse with the "variant types" that were introduced in
Delphi 2 (I think).  [I'm not sure why those C++ types think
overloading is so great when overloading of even simple
English words can cause great confusion!]

Just put a button on a Delphi form and try the following:

  procedure TForm1.Button1Click(Sender: TObject);

    TYPE
      LS_VAR =
      RECORD
        CASE iType:  INTEGER OF
          0:  (n:  DOUBLE);
          1:  (s:  pChar);
          2:  (v:  ARRAY[0..2] OF DOUBLE)
      END;

  begin
    Button1.Caption := IntToStr(SizeOf(LS_VAR));
  end;

Note:  Only one "END" even though RECORD and
CASE would normally have a separate "END".

The "answer" in the button caption is 28 bytes since
the iType is 4 bytes and the longest variant, v, is
3*8 = 24 bytes.  Note this form implies that the iType
"tag" variable determines which variant is "active."  While this
may be a useful way to look at what's going on, I think
you can directly access any variant at any time.

Since the variant tag is somewhat irrelevant, I usually
code variant records like the following that gives the
same result as above:

  TYPE
    LS_VAR =
    RECORD
      iType:  INTEGER;

      CASE INTEGER OF
        0:  (n:  DOUBLE);
        1:  (s:  pChar);
        2:  (v:  ARRAY[0..2] OF DOUBLE)
    END;

Here just use any enumerated type, INTEGER is always useful,
and just enumerate the variants in your RECORD.

Variant records are usually considered "dangerous" since you
can easily cause undesired side effects when memory locations
for variables are shared.  (Like the COMMON blocks in old
FORTRAN programs.)

efg
_________________________________________________

Earl F. Glynn          EarlGl...@WorldNet.att.net
MedTech Research Corporation
Lenexa, KS  66219  USA

 

Re:Delphi Equivalent of 'C' Union Variable Declaration?


Yes its quite possible - variant types. Look up Record Types in the help
files

If you have the VCL source, there is a great example in typinfo.pas for
a TTypedata record.

Borland's examples in the help file
type
 TPerson = record
   FirstName, LastName: string[40];
   BirthDate: TDate;
   case Citizen: Boolean of
     True: (BirthPlace: string[40]);
     False: (Country: string[20];
       EntryPort: string[20];
       EntryDate: TDate;
       ExitDate: TDate);
 end;
 TPolygon = record
   X, Y: Real;
   case Kind: Figure of
     TRectangle: (Height, Width: Real);
     TTriangle: (Side1, Side2, Angle: Real);

     TCircle: (Radius: Real);
 end;

In article <33F7FAF5.1...@discover.net>, Brian Hoffman
<bhoff...@discover.net> writes

Quote
>Help!  Is there any way to create a Delphi variable that is
>equivalent to the following 'C' union variable declaration?
>Here it is:

>        typedef struct _ls_var
>        {
>            int     type;

>            union {
>                double      number;
>                const char *string;
>                double      vector[3];
>            } data;
>        } LS_VAR;

>Thanks VERY much for any help.  

>-Brian Hoffman (bhoff...@discover.net)

Kind Regards
Claire :-)

Re:Delphi Equivalent of 'C' Union Variable Declaration?


Quote
Brian Hoffman wrote:

> Help!  Is there any way to create a Delphi variable that is
> equivalent to the following 'C' union variable declaration?
> Here it is:

>         typedef struct _ls_var
>         {
>             int     type;

>             union {
>                 double      number;
>                 const char *string;
>                 double      vector[3];
>             } data;
>         } LS_VAR;

> Thanks VERY much for any help.

> -Brian Hoffman (bhoff...@discover.net)

Here a starting point in Pascal:

type
  PChar = ^Char;

  TData = record case Byte of
    0: (ANumber: Double);
    1: (AString: PChar);
    2: (AVector: array [0..2] of Double);
  end;

  TLS_VAR = record
    AType: Byte;
    AData: TData;
  end;

var
  LS_VAR: TLS_VAR;

This is one possible solution to your task. Another way is hinted at by
the following code skeleton:

type
  TData = record case
    AType: Byte of
      0: ...
      1: ...
      2: ...
  end;

You will have to check types for equivalence (int <=> integer ?).
Forgive typos.

Achim

Re:Delphi Equivalent of 'C' Union Variable Declaration?


Help!  Is there any way to create a Delphi variable that is
equivalent to the following 'C' union variable declaration?
Here it is:

        typedef struct _ls_var
        {
            int     type;

            union {
                double      number;
                const char *string;
                double      vector[3];
            } data;
        } LS_VAR;

Thanks VERY much for any help.  

-Brian Hoffman (bhoff...@discover.net)

Re:Delphi Equivalent of 'C' Union Variable Declaration?


Quote
Brian Hoffman wrote:

 > Is there any way to create a Delphi variable that is

Quote
> equivalent to the following 'C' union variable declaration?

>         typedef struct _ls_var
>         {
>             int     type;

>             union {
>                 double      number;
>                 const char *string;
>                 double      vector[3];
>             } data;
>         } LS_VAR;

type
  TLsVar = record
             VarType: Integer;
             Data:    record
                      case Byte of
                        0: (Number:  Double);
                        1: (Letters: PChar);
                        2: (Vector:  array[0..2] of Double)
                      end
           end;

Chris.

PS: some field-indentifiers changed to prevent clashes with Delphi's
    reserved words. You will also have to investigate whether or not
    to "pack" the records to make everything binary compatible (i.e.
    replace "record" with "packed record")

Other Threads