在Aimingoo主页《如何跨单元、跨类地访问Delphi 类的私有域方法》
那里有个函数,是取堆指针长度的,而我们所用的对象也是一个指针,所以,可以用它来判断,如下:
/// <summary>
/// 得到堆指针的指针长度,如一个对象或动态得到的指针
/// 如:
/// if : GetMem(P, 10);
/// then: Len := GetPtrSize(P) ==> 10
///
/// if : Obj := TObject.Create;
/// then: Len := GetPtrSize(Obj) ==> Obj.InstanceSize;
/// if : Obj.Free;
/// then: Len := GetPtrSize(Obj) ==> 0;
///
/// 不能是栈指针的指针,如临时、局部变量的取地址得到的指针
/// </summary>
function GetPtrSize(P: PChar): Integer;
const
cThisUsedFlag = 2;
cPrevFreeFlag = 1;
cFillerFlag = Integer($80000000);
cFlags = cThisUsedFlag or cPrevFreeFlag or cFillerFlag;
type
PUsed = ^TUsed;
TUsed = packed record
sizeFlags: Integer;
end;
begin
Result := 0;
Dec(P, sizeof(TUsed));
if (PUsed(P).sizeFlags and cThisUsedFlag) <> 0 then
begin
Result := PUsed(P).sizeFlags and not cFlags;
if (PUsed(P).sizeFlags and cFillerFlag) = 0 then //取实际长度
Dec(Result, sizeof(TUsed));
end;
end;
Call:
if GetPtrSize(Pointer(Self)) = 0 then
raise Exception.Create('Self is invalid');