Thema: Delphi Pointer is TObject?

Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#8

Re: Pointer is TObject?

  Alt 4. Dez 2007, 08:32
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*}
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat