素与TVarRec 类型元素兼容。
注意:不要把TVarRec 记录类型和Variant 类型使用的TVarData 记录类型相混淆。这两种类型用途不同,而且互不兼容。甚至可容纳的数据类型也不同,因为TVarRec 支持Delphi 数据类型,而TVarData 支持OLE 数据类型。
TVarRec 记录类型结构如下:
type
TVarRec = record case Byte of
vtInteger: (VInteger: Integer; VType: Byte); vtBoolean: (
VBoolean: Boolean); vtChar: (VChar: Char);
vtExtended: (VExtended: PExtended); vtString: (VString: PShortString); vtPointer: (VPointer: Pointer); vtPChar: (VPChar: PChar); vtObject: (VObject: TObject); vtClass: (VClass: TClass);
vtWideChar: (VWideChar: WideChar); vtPWideChar: (VPWideChar: PWideChar); vtAnsiString: (VAnsiString: Pointer); vtCurrency: (VCurrency: PCurrency); vtVariant: (VVariant: PVariant); vtInterface: (VInterface: Pointer); end;
每种记录都有一个VType 域,乍一看不容易发现,因为它与实际意义的整型类型数据(通常是一个引用或一个指针)放在一起,只被声明了一次。 利用上面信息我们就可以写一个能操作不同类型数据的函数。下例的SumAll 函数,通过把字符串转成整数、字符转成相应的序号、True布尔值加一,计算不同类型数据的和。这段代码以一个case语句为基础,虽然不得不经常通过指针取值,但相当简单,:
function SumAll (const Args: array of const): Extended; var
I: Integer; begin
Result := 0;
for I := Low(Args) to High (Args) do case Args [I].VType of vtInteger: Result :=
Result + Args [I].VInteger; vtBoolean:
if Args [I].VBoolean then
Result := Result + 1; vtChar:
Result := Result + Ord (Args [I].VChar); vtExtended:
Result := Result + Args [I].VExtended^; vtString, vtAnsiString:
Result := Result + StrToIntDef ((Args [I].VString^), 0); vtWideChar:
Result := Result + Ord (Args [I].VWideChar); vtCurrency:
Result := Result + Args [I].VCurrency^; end; // case end;
我已在例OpenArr中加了这段代码,该例在按下设定的按钮后调用SumAll 函数。
procedure TForm1.Button4Click(Sender: TObject); var
X: Extended; Y: Integer; begin
Y := 10;
X := SumAll ([Y * Y, 'k', True, 10.34, '99999']); ShowMessage (Format (
'SumAll ([Y*Y, ''k'', True, 10.34, ''99999'']) => %n', [X])); end;
在图6.2中,你可以看到调用函数的输出和例OpenArr的窗体。 图 6.2: 例OpenArr的窗体,当按Untype按钮出现的信息框
Delphi 调用协定
32位的Delphi 中增加了新的参数传递方法,称为fastcall:只要有可能,传递到CPU寄存器的参数能多达三个,使函数调用操作更快。这种快速调用协定(Delphi 3确省方式)可用register 关键字标示。
问题是这种快速调用协定与Windows不兼容,Win32 API 函数必须声明使用stdcall 调用协定。这种协定是Win16 API使用的原始Pascal 调用协定和C语言使用的cdecl 调用协定的混合体。
除非你要调用外部Windows函数或定义Windows 回调函数,否则你没有理由不用新增的快速调用协定。 在后面你会看到使用stdcall 协定的例子,在Delphi帮助文件的Calling conventions 主题下,你能找到有关Delphi调用协定的总结内容。
什么是方法?