- 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.
- 2.2.6.11. -