Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Pointer is TObject? (https://www.delphipraxis.net/104404-pointer-tobject.html)

Neutral General 3. Dez 2007 12:41


Pointer is TObject?
 
Hi,

Wie kann man herausfinden ob ein Pointer auf ein Objekt zeigt? Also die Methode der Überschrift funktioniert (schon allein vom Compiler her) nicht.

Gruß
Neutral General

Nuclear-Ping 3. Dez 2007 12:44

Re: Pointer is TObject?
 
Gibts da nicht IsObject oder IsClass? :gruebel:

dominikkv 3. Dez 2007 12:55

Re: Pointer is TObject?
 
mal einfach ins blaue geraten:
Delphi-Quellcode:
if MyPointer <> NIL then
  if MyPointer^ is TObject then
    // ...;

sirius 3. Dez 2007 13:11

Re: Pointer is TObject?
 
Zitat:

Zitat von Nuclear-Ping
Gibts da nicht IsObject oder IsClass? :gruebel:

IsClass gibt es (wenn auch versteckt). Wird aufgerufen, wenn man dies schreibt: "if Sender is TIrgendetwas".
(TIrgendetwas darf nur nicht TObject sein, da wird nur überprüft ab Sender<>nil ist)
Es wird dann TObject.Inheritsfrom aufgerufen, was bei allen "NichtObjekten" zu einem Fehler führen könnte. Damit hätte man dies überprüft.

Ähnliches erreicht man z.B. damit:
Delphi-Quellcode:
function isObject(aObject:pointer):boolean;
//type ppointer=^pointer;
var pp:ppointer;
begin
  pp:=pointer(aObject);
  try
    result:= (ppointer(integer(pp^)+vmtselfptr)^=pp^)
  except
    result:=false;
  end;
end;
...um mal so die grundlegende Struktur eines Objektes zu überprüfen.

Direkt eine gängige Funktion bzw überhaupt eine Möglichkeit ist mir nicht bekannt. Es wird ja nirgends gespeichert, was in dem Pointer ist.
Du könntest es allerdings mit TVarRec bzw. sogar Variant umgehen (bei letzterem bin ich mir nicht sicher).

Neutral General 3. Dez 2007 16:12

Re: Pointer is TObject?
 
Hi,

Habs jetzt so gemacht und das funktioniert bisher ganz gut:

Delphi-Quellcode:
function IsObject(p: Pointer): Boolean;
begin
  Result := TObject(p).ClassType <> nil;
end;
Gruß
Neutral General

peschai 4. Dez 2007 05:45

Re: Pointer is TObject?
 
@Neutral General:
Macht BUMM wenn dein pointer NIL ist ... Try except end ?
... un dbin mir nicht sicher wie verlässlich das ist ?

SirThornberry 4. Dez 2007 06:30

Re: Pointer is TObject?
 
Ich glaub all diese Methoden können BUMM machen. Hat man Beispielsweise einen Pointer der nur auf ein einzelnes Byte zeigt und es wird versucht mehr zu lesen dort wo er hinzeigt kann es gewaltig BUMM machen (denke ich zumindest).

himitsu 4. Dez 2007 07:32

Re: Pointer is TObject?
 
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%

Delphi-Quellcode:
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:
Delphi-Quellcode:
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*}

Lossy eX 4. Dez 2007 08:11

Re: Pointer is TObject?
 
Wäre es nicht evtl besser, wenn man gar nicht erst in solch eine Lage kommen würde? Das auf so eine Art und Weise überprüfen zu müssen halte ich generell für Fragwürdig. Zu mal ich solch einen Stil auch für unsauber halte. Ich versuche mal was und wenn es nicht klappt, dann hoffe ich, dass der Exceptionblack mir schon den Arsch retten wird. Das Beste ist gar nicht erst in solche Situationen zu kommen. Und für mich schreit das nach einem Designfehler innerhalb des Programms. Aber das kann ich nicht abschätzen, da ich das Programm nicht kenne.

DMW 4. Dez 2007 14:19

Re: Pointer is TObject?
 
Du sprichst mir aus der Seele.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:08 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz