Previous: 2.2.6.10. String Types To the Table of Contents Next: 2.2.6.12. Set Types
2.2.6.10. String Types Table of Contents 2.2.6.12. Set Types

- 2.2.6.11. -
Table of Contents
2. TMT Pascal Language Description
2.2. Pascal Language Structure
2.2.6. Types
2.2.6.11. Variant Types


2.2.6.11. Variant Types


TMT Pascal implements two COM-compatible variant types: Variant and OleVariant which are absolutely identical. These types represent values that can change their type at runtime. Variants offer greater usability but occupy more memory than regular variables, and operations on them are slower than on statically bound types. Furthermore, illegal operations on variants often result in runtime errors.

A variant occupies 16 bytes of memory and consists of a type code and a value, or pointer to a value, of the type specified by the code.

Variants can hold values of following types: Variants can mix with other variants and with integer, real, null-terminated wide string (PWChar), and Boolean values in expressions and assignments; the compiler automatically performs type conversions.

The following code demonstrates some of the automatic conversions performed when variants are mixed with other types.
{$ifdef __GUI__}
  uses WinCRT;
{$endif}

var
  V1, V2, V3, V4: Variant;
  D: Double;

begin
  V1 := 2001;
  Writeln(V1);  // integer value

  V2 := pi;
  Writeln(V2);  // real value
  V3 :=  '1234.5678';
  Writeln(V3);  // null-terminated wide string value
  V4 := V1 > V2;
  Writeln(V4);  // Boolean value

  D := V1 + V2 + V3;
  Writeln(D);   // real value 3.23870939265359E+0003

end.
Special conversion rules apply to the PWChar type. When a PWChar is converted to any other type, it is first converted to a Double, then converted to a destination type. On other hand, an integer, real, or Boolean could not be converted into a PWChar value.

Use a special tagVARIANT type to specify variant data that cannot be passed by reference. tagVARIANT is declared in the ActiveX.PAS unit as shown below:
type
  PVariantArg = ^TVariantArg;
  tagVARIANT  = record
    vt: TVarType;
    wReserved1: Word;
    wReserved2: Word;
    wReserved3: Word;
    case Integer of
                     VT_UI1: (bVal: Byte);
                      VT_I2: (iVal: Smallint);
                      VT_I4: (lVal: Longint);
                      VT_R4: (fltVal: Single);
                      VT_R8: (dblVal: Double);
                    VT_BOOL: (vbool: TOleBool);
                   VT_ERROR: (scode: HResult);
                      VT_CY: (cyVal: Currency);
                    VT_DATE: (date: TOleDate);
                    VT_BSTR: (bstrVal: TBStr);
                 VT_UNKNOWN: (unkVal: Pointer);
                VT_DISPATCH: (dispVal: Pointer);
                   VT_ARRAY: (parray: PSafeArray);
         VT_BYREF or VT_UI1: (pbVal: ^Byte);
          VT_BYREF or VT_I2: (piVal: ^Smallint);
          VT_BYREF or VT_I4: (plVal: ^Longint);
          VT_BYREF or VT_R4: (pfltVal: ^Single);
          VT_BYREF or VT_R8: (pdblVal: ^Double);
        VT_BYREF or VT_BOOL: (pbool: ^TOleBool);
       VT_BYREF or VT_ERROR: (pscode: ^HResult);
          VT_BYREF or VT_CY: (pcyVal: ^Currency);
        VT_BYREF or VT_DATE: (pdate: ^TOleDate);
        VT_BYREF or VT_BSTR: (pbstrVal: ^TBStr);
     VT_BYREF or VT_UNKNOWN: (punkVal: ^IUnknown);
    VT_BYREF or VT_DISPATCH: (pdispVal: ^IDispatch);
       VT_BYREF or VT_ARRAY: (pparray: ^PSafeArray);
     VT_BYREF or VT_VARIANT: (pvarVal: PVariant);
                   VT_BYREF: (byRef: Pointer);
                      VT_I1: (cVal: Char);
                     VT_UI2: (uiVal: Word);
                     VT_UI4: (ulVal: LongWord);
                     VT_INT: (intVal: Integer);
                    VT_UINT: (uintVal: LongWord);
     VT_BYREF or VT_DECIMAL: (pdecVal: PDecimal);
          VT_BYREF or VT_I1: (pcVal: PChar);
         VT_BYREF or VT_UI2: (puiVal: PWord);
         VT_BYREF or VT_UI4: (pulVal: PInteger);
         VT_BYREF or VT_INT: (pintVal: PInteger);
        VT_BYREF or VT_UINT: (puintVal: PLongWord);
    end;
  TVariantArg = tagVARIANT;
The first field contains the argument's type, and the fifth contains its value. To pass a long integer, for example, the vt and iVal fields of the tagVARIANT structure would be filled with VT_I4 (long integer) and the actual value of the long integer.


Previous: 2.2.6.10. String Types To the Table of Contents Next: 2.2.6.12. Set Types
2.2.6.10. String Types Table of Contents 2.2.6.12. Set Types

- 2.2.6.11. -