AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Überprüfen, ob ein Pointer auf ein Objekt zeigt
Thema durchsuchen
Ansicht
Themen-Optionen

Überprüfen, ob ein Pointer auf ein Objekt zeigt

Ein Thema von fajac · begonnen am 3. Nov 2009 · letzter Beitrag vom 4. Nov 2009
Antwort Antwort
fajac

Registriert seit: 1. Jul 2009
60 Beiträge
 
#1

Überprüfen, ob ein Pointer auf ein Objekt zeigt

  Alt 3. Nov 2009, 13:09
Hallo Experten, folgendes Problem:

Ich möchte eine Listenklasse erstellen, die von TList abgeleitet ist. In allen Methoden, die einen Pointer zur Liste hinzufügen oder einen entfernen, möchte ich, falls es sich bei dem übergebenen Pointer um ein Objekt eines bestimmten Typs handelt, eine Methode davon aufrufen. Zur Überprüfung, ob es sich um diesen Typ handelt, benutze ich den is-Operator.
Diese Liste möchte ich applikationsweit als Ersatz von TList verwenden.

Das funktioniert auch wunderbar, solange die Liste ausschließlich mit Objekten gefüttert wird. Aber wehe, man versucht das mit Zeigern auf Records, dann gibt es eine AV - hier ein Beispiel:

Delphi-Quellcode:
type
  TMyObject = class (TObject) { Der Typ, auf den ich prüfen möchte }
  public
    procedure DoSomething();
  {...}
  end;

  TMyList = class (TList)
  public
    function Add (AItem : Pointer) : Integer; reintroduce;
    {...}
  end;

implementation
  
function TMyList.Add (AItem : Pointer) : Integer;
var
  obj : TObject;
begin
  obj := AItem; { Cast auf TObject, um "is" anwenden zu können }
  if obj is TMyObject then { <== hier schepperts, wenn AItem ein "normaler" Zeiger ist }
    TMyObject (AItem).DoSomething;
  Result := inherited Add (AItem);
end;
Ich bin mir darüber im klaren, dass der Cast auf TObject an sich schon problematisch ist - aber mir fällt keine andere Möglichkeit ein, herauszufinden um was es sich bei dem Pointer handelt. Natürlich könnte man die Exception abfangen und dann davon ausgehen, dass AItem kein Objekt ist, aber das fände ich auch unsauber.
Kann jemand helfen?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Überprüfen, ob ein Pointer auf ein Objekt zeigt

  Alt 3. Nov 2009, 13:20
Sowas ist nicht 100%ig möglich.

einzige wirkliche Lösung: Pointer und Objekte getrennt verwalten


TObject(P) is TXyz liefert bei Objekten richtige Lösungen (solange das Objekt nicht durch z.B. einen Bufferoverflow zerstört wurde),
aber in anderen Daten, wie z.B. einem Record, können zufällig Werte vorhanden sein, welche der "Signatur" eines Objektes entsprechen, wodurch der Record dann als Objekt erkannt würde.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: Überprüfen, ob ein Pointer auf ein Objekt zeigt

  Alt 3. Nov 2009, 13:21
Zitat von fajac:
Ich bin mir darüber im klaren, dass der Cast auf TObject an sich schon problematisch ist
Ja, aber es gibt keine andere Möglichkeit. Du kannst auch nicht prüfen, ob ein Zeiger auf ein Objekt zeigt. Es gäbe bestimmte Tricks, aber nichts ist sicher.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

Re: Überprüfen, ob ein Pointer auf ein Ojekt zeigt

  Alt 3. Nov 2009, 13:24
Delphi-Quellcode:
function PointsToObj(P: Pointer): Boolean;
begin
  try
    Result := TObject(P).ClassName <> '';
  except
    Result := false;
  end;
end;
Konnts mir nicht verkneifen
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#5

Re: Überprüfen, ob ein Pointer auf ein Objekt zeigt

  Alt 3. Nov 2009, 13:42
Hallo,

der folgende Code basiert auf einer Vorlage von Hallvard Vassbotn:

Delphi-Quellcode:
function IsValidObject (const aObject: TObject): Boolean;
type
  PVmt = ^TVmt;
  TVmt = packed record
    SelfPtr: TClass;
    ignored: array [0..-(4 + vmtSelfPtr) - 1] of Byte;
  end;
var
  VMT: PVmt;
begin
  Result := False;

  if {Windows.}IsBadReadPtr(aObject, 4) then
    Exit;

  VMT := PVmt(aObject.ClassType);
  Dec (VMT);

  if IsBadReadPtr(VMT, 4) then
    Exit;

  if (aObject.ClassType = VMT.SelfPtr) then
    Result := True;
end;
Die Anmerkung von himitsu bezüglich der getrennten Verwaltung von Pointern und Objekten sollte trotzdem beachtet werden. Der Code könnte aber beim Debuggen nützlich sein.

Gruß Hawkeye
  Mit Zitat antworten Zitat
fajac

Registriert seit: 1. Jul 2009
60 Beiträge
 
#6

Re: Überprüfen, ob ein Pointer auf ein Objekt zeigt

  Alt 3. Nov 2009, 15:15
Vielen Dank für Eure Antworten - leider habe ich mir sowas schon gedacht...
Natürlich ist der Hinweis, die Verwaltung der Objekte von der der Zeiger zu trennen völlig richtig - das Problem ist, dass ich hier ein ziemlich altes und krudes Projekt bearbeiten muss und mir gedacht habe, dass ich mit der neuen Liste da etwas Ordnung schaffen könnte...war wohl nix.
Gruß
Frank
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.005 Beiträge
 
Delphi 2009 Professional
 
#7

Re: Überprüfen, ob ein Pointer auf ein Objekt zeigt

  Alt 3. Nov 2009, 15:30
Zitat von fajac:
Diese Liste möchte ich applikationsweit als Ersatz von TList verwenden.

Das funktioniert auch wunderbar, solange die Liste ausschließlich mit Objekten gefüttert wird.
Ok, dann nimm eine Klasse die einen Pointer als einzige Property enthält. Ein Workaround, aber wenn es der Codeverbesserung dienlich ist ...

Objekte dieses Typs können dann leicht mit is erkannt werden.

Delphi-Quellcode:
TMyPointerHolder = class
private
  FP: Pointer;

public
  property P: Pointer read FP write FP;

end;
Viele Grüße,
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Überprüfen, ob ein Pointer auf ein Objekt zeigt

  Alt 3. Nov 2009, 15:40
@General: ich konnte es mir auch nicht verkneifen
Delphi-Quellcode:
var x: Array[0..100] of Integer;
  P: PInteger;
begin
  X[30] := $6d696807;
  X[31] := $75737469;
  X[40] := Integer(@X[30]);
  X[51] := Integer(@X[51]);
  P := @X[51];
  if PointsToObj(P) then
    ShowMessage('Ja, ich bin eine Klasse, und mein Klassenname ist "'
      + TObject(P).ClassName + '"');
  if not IsValidObject(TObject(P)) then
    ShowMessage('Ich bin zwar zufällig kein valides Object, '
      + 'aber das kann man leicht ändern *grins*');
Gut, IsValidObject hat duch mehr Abfragen eine höhere Wahrscheinlichkeit, daß es richtig liegt,
aber dennoch kann es immernoch mal falsch liegen.

Nein, ich bin nicht so sehr selbstverliebt, aber dieser Name paßte nunmal zufällig genau rein
(und ich verrate nicht, was ich mit diesem Satz meine ... wer es gesehn hat, der weiß es)

[add]
so, der obere Code funktioniert mit D7 und wer weiß womit sonst noch,
so wie ich es will ... ansonsten funktioniert er zwar, aber der Name gefällt mir nicht ... drum hier noch 'ne etwas angepaßtere Version
der and
Delphi-Quellcode:
var x: Array[0..100] of Integer;
  P: PInteger;
  i: Integer;
begin
  i := 40 - vmtClassName shr 2;
  X[30] := $6d696807;
  X[31] := $75737469;
  X[40] := Integer(@X[30]);
  X[ i] := Integer(@X[ i]);
  P := @X[i];
  if PointsToObj(P) then
    ShowMessage('Ja, ich bin eine Klasse, und mein Klassenname ist "'
      + TObject(P).ClassName + '"');
  //if not IsValidObject(TObject(P)) then
  // ShowMessage('Ich bin zwar zufällig kein valides Object, '
  // + 'aber das kann man leicht ändern *grins*');
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.429 Beiträge
 
Delphi 10.4 Sydney
 
#9

Re: Überprüfen, ob ein Pointer auf ein Objekt zeigt

  Alt 4. Nov 2009, 08:29
Ich würde das Problem so angehen:
Delphi-Quellcode:
  TMyList = class (TObjectList)
    constructor Create;
  public
    {...} 
  end;

constructor TMyList.Create;
begin
  inherited;
  OwnsObjects := False;
end;
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:06 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