请考虑以下代码:
procedure Test;
var
IntGenuine: UInt64;
IntVariant: Variant;
begin
IntGenuine := 0;
IntVariant := UInt64(0); // The type of the variant is UInt64 now
WriteLn('Size of IntGenuine = ', SizeOf(IntGenuine)); // Output: 8
WriteLn('Size of IntVariant = ', SizeOf(IntVariant)); // Output: 24
end;
我知道声明SizeOf(IntVariant)
等同于SizeOf(Variant)
。它获取类型Variant
的大小,而不是变体的实际类型的大小(在这种情况下为UInt64
)。
如何获取给定变体的实际类型的内存大小?
答案 0 :(得分:3)
你可以创建一个像这样的函数:
SELECT id, date
FROM table
WHERE str_to_date(date, '%m/%d/%Y') BETWEEN '2015-09-10' and '2015-09-23';
这里Program Project1;
{$APPTYPE CONSOLE}
uses
Variants, SysUtils;
function GetVarTypeSize(AVarType : TVarType; var isArray : boolean) : integer;
begin
isArray := AVarType <> (AVarType and VarTypeMask);
case AVarType and VarTypeMask of
varSmallInt: result := SizeOf(SmallInt);
varInteger: result := SizeOf(Integer);
varSingle: result := SizeOf(Single);
varDouble: result := SizeOf(Double);
varCurrency: result := SizeOf(Currency);
varDate: result := SizeOf(TDateTime);
varOleStr: result := SizeOf(PWideChar);
varDispatch: result := SizeOf(Pointer);
varError: result := SizeOf(HRESULT);
varBoolean: result := SizeOf(WordBool);
varUnknown: result := SizeOf(Pointer);
varShortInt: result := SizeOf(ShortInt);
varByte: result := SizeOf(Byte);
varWord: result := SizeOf(Word);
varLongWord: result := SizeOf(LongWord);
varInt64: result := SizeOf(Int64);
varUInt64: result := SizeOf(UInt64);
varString: result := SizeOf(Pointer);
varAny: result := SizeOf(Pointer);
varArray: result := SizeOf(PVarArray);
varByRef: result := SizeOf(Pointer);
varUString: result := SizeOf(Pointer);
varRecord: result := SizeOf(TVarRecord);
else
result := -1; //unknown
end;
end;
var
v : Variant;
b : boolean;
begin
v := 3.141592654; // double
Write(GetVarTypeSize(VarType(v), b));
if b then WriteLn(' : Is array') else WriteLn;
v := 3; // byte
Write(GetVarTypeSize(VarType(v), b));
if b then WriteLn(' : Is array') else WriteLn;
v := integer(3); // integer
Write(GetVarTypeSize(VarType(v), b));
if b then WriteLn(' : Is array') else WriteLn;
v := Now; // DateTime
Write(GetVarTypeSize(VarType(v), b));
if b then WriteLn(' : Is array') else WriteLn;
v := VarArrayCreate([0,9], varDouble); //array ! careful
Write(GetVarTypeSize(VarType(v), b));
if b then WriteLn(' : Is array') else WriteLn;
ReadLn;
end.
将掩盖定义变量数组的位。如果基本变量是数组类型,则屏蔽它将告诉您数组元素的类型。
您可以阅读更多in the documentation。
答案 1 :(得分:2)
如果你的变量是variant
,它将在Win32下使用(至少)16个字节,在Win64下使用24个字节,存储任何值。
此变量的内存大小始终是variant
结构之一,TVarData
中定义为System.pas
。
定义:
var
IntVariant: Variant;
实际上与定义相同:
var
IntVariant: TVarData;
使用一些初始化/终结魔术:
var
IntVariant: TVarData;
begin
IntVariant.VType := varEmpty;
try
...
finally
VarClear(variant(IntVariant));
end;
end;
如果您不存储任何内容(varEmpty
或varNull
),它仍会使用16/24字节。如果存储boolean
,它仍将使用16/24字节。如果它存储了一些string
,则必须将堆分配的存储文本值添加到16/24字节。
答案 2 :(得分:2)
变体存储在幕后类型TVarData
的记录中。
PVarData = ^TVarData;
TVarData = packed record
case Integer of
0: (VType: TVarType;
case Integer of
0: (Reserved1: Word;
case Integer of
0: (Reserved2, Reserved3: Word;
case Integer of
varSmallInt: (VSmallInt: SmallInt);
varInteger: (VInteger: Integer);
varSingle: (VSingle: Single);
varDouble: (VDouble: Double);
varCurrency: (VCurrency: Currency);
varDate: (VDate: TDateTime);
varOleStr: (VOleStr: PWideChar);
varDispatch: (VDispatch: Pointer);
varError: (VError: HRESULT);
varBoolean: (VBoolean: WordBool);
varUnknown: (VUnknown: Pointer);
varShortInt: (VShortInt: ShortInt);
varByte: (VByte: Byte);
varWord: (VWord: Word);
varLongWord: (VLongWord: LongWord);
varInt64: (VInt64: Int64);
varUInt64: (VUInt64: UInt64);
varString: (VString: Pointer);
varAny: (VAny: Pointer);
varArray: (VArray: PVarArray);
varByRef: (VPointer: Pointer);
varUString: (VUString: Pointer);
varRecord: (VRecord: TVarRecord);
//$ffff: (VLargest: TLargestVarData);
);
1: (VLongs: array[0..{$IFDEF CPUX64}4{$ELSE}2{$ENDIF}] of LongInt);
);
2: (VWords: array [0..{$IFDEF CPUX64}10{$ELSE}6{$ENDIF}] of Word);
3: (VBytes: array [0..{$IFDEF CPUX64}21{$ELSE}13{$ENDIF}] of Byte);
);
1: (RawData: array [0..{$IFDEF CPUX64}5{$ELSE}3{$ENDIF}] of LongInt);
end;
可以获取您要查找的信息,将Variant
变量转换为此类型:
var
varData: TVarData;
intVariant: Variant;
size: Integer;
begin
intVariant := UInt64(10);
varData := TVarData(IntVariant);
case varData.VType of
varUInt64: size := SizeOf(varData.VUInt64);
varInteger: size := SizeOf(varData.VInteger);
. . .
end;
end;
...但以上不是通常的方法:
var
intVariant: Variant;
size: Integer;
vType: Integer;
begin
vType := VarType(intVariant) and VarTypeMask;
case vType of
varUInt64: size := SizeOf(UInt64);
varInteger: size := SizeOf(Integer);
. . .
end;
end;