Delphi-Quellcode:
function isObject(aObject: Pointer): Boolean;
// wenn PPointer nicht definiert ist, dann PInteger verwenden
begin
try
Result := PPointer(aObject)(PInteger(aObject)^ + vmtselfptr)^ = PPointer(aObject)^;
except
Result := false;
end;
end;
@SirThornberry: drum hatte ich gestern mal versucht sirius ohne Try-Except, aber dafür mit IsBadReadPtr umzuschreiben, aber
MSDN: This function is obsolete and should not be used.
leider gibt es wohl keinen Ersatz dafür und mam müßte auch noch mehrere (mindestens 5) Speicherbereich überprüfen, so daß ich es bei Try-Except beließ.
da hier mehrere Werte geprüft werden, ist die Wahrscheinlichkeit, daß man ein Ojekt richtig erkenne natürlich höher, aber selbst hier kann man reinfallen ... nichts ist 100%ig sicher (wen man rein zufällig eine Struktur vorfindet, wo passende Werte drin vorkommen)
Nja, 100%ig geht nicht, man kann höchstens soviel wie möglich prüfen
(vmtTypeInfo, vmtClassName und vmtInstanceSize bieten sich noch an),
aber da sirius einen Bereich auf nur einen bestimmten Wert überprüft und diese(r) Bereich(e) auch noch mehrmals umgeleitet werden, sollte sich schon eine hohe Wahrscheinlichkeit ergeben, daß sein Ergebnis stimmt.
wenn man alleine von den Wertebereichen der verglichenen Bereiche ausgeht, dann liegt das bei:
(also wenn alle (De)Refferenzierungen ohne
Exception ablaufen)
sirius: Pointer = Pointer : 1 von 64 Bit richtig = 99,999999999999999994578989137572%
Neutral General: Pointer <> 0 : 1 von 32 Bit falsch = 0,000000023283064365386962890625%
Result := TObject(p).ClassType <> nil;
dieses wird aber wohl oft nicht so funktionieren, denn
Delphi-Quellcode:
function TObject.ClassType: TClass;
begin
Pointer(Result) := PPointer(Self)^;
end;
was dann auf dieses rauskommt:
Result := PPointer(P)^ <> nil;
wenn
P = nil oder wenn
P oder
PPointer(P)^ auf einen Speicher ohne Leserechte oder einen nicht Vorhandenen zeigt, dann kracht's.
Und wenn
PPointer(P)^ <> nil, dann heißt es noch lange nicht, daß es ein Objekt ist, da es ja dem entspricht
PInteger(P)^ <> 0 und dort alles ungleich 0 (egal was es ist) als Richtig anerkannt wird.
PS: zu Neutral General's IsObject
Delphi-Quellcode:
function IsObject(p: Pointer): Boolean;
begin
try
Result := TObject(p).ClassType <>
nil;
except
Result := False;
Application.MessageBox('
Ohhh, eine Exception', '
Fehler');
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var S:
String;
begin
S := '
';
If not IsObject(Pointer(S))
Then
Application.MessageBox('
"" ist kein Object', '
OK');
S := '
123';
If IsObject(Pointer(S))
Then
Application.MessageBox('
"123" ist ein Object °_°', '
Falsch');
end;
Anworten wie sie vom Programm hintereinander angezeigt werden {incl. meiner Kommentare}:
Ohhh, eine
Exception {war klar, weil P=nil}
"" ist kein Object {jupp, nil ist kein Object}
"123" ist ein Object °_° {nja, PPointer(P)^ is zumindestens nicht nil, also stimmt *hust*}