As @DavidHeffernan correctly pointed out, class types are pointers, so they are semantically equivalent, and there is no way to distinguish them without storing type directives.
However, if you ask, "How do I know if arbitrary pointers to an instance of an object are given?" there is a solution for this:
/// <summary> /// Verifies that the argument points to valid object instance. /// </summary> /// <exception cref="EAccessViolation"> /// If segmentation fault occurs while reading VMT and/or its field from the /// specified memory address. /// </exception> /// <remarks> /// Delphi only, incompatible with FPC. /// </remarks> /// <example> /// <code> /// procedure TForm1.FormCreate(Sender: TObject); /// begin /// ShowMessage(BoolToStr(IsInstance(Self), True)); /// end; /// </code> /// </example> function IsInstance(Data: Pointer): Boolean; var VMT: Pointer; begin VMT := PPointer(Data)^; Result := PPointer(PByte(VMT) + vmtSelfPtr)^ = VMT; end;
I have posted all the documentation on the embedded document, so I believe that no more comments are needed, but I want to reiterate that intentionally invalid pointers, such as Pointer(7) your example, will most likely cause an access violation error. Thus, you can perform a preliminary check if the highest Word pointer is zero (only the same logic as in the Windows.IS_INTRESOURCE macro:
function Is_IntResource(lpszType: PChar): BOOL; begin Result := ULONG_PTR(lpszType) shr 16 = 0; end;
source share