| Autor |
Beitrag |
Deerfield
      
Beiträge: 35
Delphi XE Pro
|
Verfasst: Mi 19.10.11 13:22
Hallo,
beim Aufruf einer Prozedur
procedure test(aParam: Integer);
übergebe ich zum einen Integerwerte, gelegentlich aber auch ein Objekt, dass hart als Integer gecastet übergeben wird
test(Integer(MeinObjekt));
Gibt es eine Möglichkeit, in der Prozedur selbst dann zu prüfen (ohne eine Exception zu provozieren), ob der übergebene Wert ein Objekt ist?
Routinen a la 'as', 'is' oder Assigned() bringen nicht den gewünschten Erfolg, die Funktion selbst kann ich aus projekttechnischen Gründen aber auch nicht einfach überladen... Moderiert von Narses: Topic aus Sonstiges (Delphi) verschoben am Mi 19.10.2011 um 15:51
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Mi 19.10.11 13:35
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| Procedure Test(p:Integer); var isWahrscheinlichObj:Boolean; begin if Assigned(TObject(p)) then begin try TObject(p).ClassName; isWahrscheinlichObj := true; except isWahrscheinlichObj := false; end; end; ShowMessage(IntToStr(Integer(isWahrscheinlichObj))); end; |
funktioniert schon, aber beides Integer und Objekte auf gut Glück zu übergeben ist schon strange ....
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
Deerfield 
      
Beiträge: 35
Delphi XE Pro
|
Verfasst: Mi 19.10.11 13:42
Assigned bringt immer true zurück, auch wenn der Integer Wert auf kein Objekt zeigt. Ich muss auf den Typ TMeinObjekt prüfen können, und das ohne eine Exception zu provozieren 
Zuletzt bearbeitet von Deerfield am Mi 19.10.11 13:43, insgesamt 1-mal bearbeitet
|
|
Lemmy
      
Beiträge: 792
Erhaltene Danke: 49
Windows 7 / 10; CentOS 7; LinuxMint
Delphi 7-XE10.1, VS 2015
|
Verfasst: Mi 19.10.11 13:42
Hi,
Deerfield hat folgendes geschrieben : |
übergebe ich zum einen Integerwerte, gelegentlich aber auch ein Objekt, dass hart als Integer gecastet übergeben wird
... die Funktion selbst kann ich aus projekttechnischen Gründen aber auch nicht einfach überladen... |
ich würde mir an deiner Stelle DRINGENST Gedanken über das Design des Projekts bzw. der Methode machen.
ein
Delphi-Quelltext 1:
| procedure test(aParam: Integer; AObject:TObject=nil); |
würde nicht gehen? Ändert zwar nichts am Design aber zumindest wird etwas klarer was da passiert...
GRüße
|
|
Deerfield 
      
Beiträge: 35
Delphi XE Pro
|
Verfasst: Mi 19.10.11 13:44
Ich bin auf diese Prozedur angewiesen, muss aber mehr Daten als Parameter übergeben, deshalb mache ich ja solche Klimmzüge... Der übergebene Parameter vom Typ Integer wird von mehreren anderen Prozeduren benutzt bzw. an diese übergeben, am Ende muss ich auswerten, ob denn nur der Integer Wert dran hängt (->Behandlungsroutine 1) oder mein Objekt TMeinObjekt (->Behandlungsroutine 2).
|
|
jasocul
      
Beiträge: 6395
Erhaltene Danke: 149
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mi 19.10.11 14:25
Dann stelle das Programm so um, dass IMMER ein Objekt übergeben wird.
Dann musst du gar nichts prüfen.
Dein Objekt muss natürlich dann auch die Möglichkeit haben, einen Integer zu übergeben. Das sollte aber das kleinere Problem sein.
|
|
Deerfield 
      
Beiträge: 35
Delphi XE Pro
|
Verfasst: Mi 19.10.11 14:29
Genau das war auch die einzige Variante, die ich gesehen habe. Ist halt nur ein heiden Aufwand, weil ich alles bestehende anfassen muss, hab das schon paar mal durch. Ist schon komisch, dass man ein Objekt derart casten kann, dann aber nicht mehr auswerten... if (TObject(aParam) is TMeinObjekt) wäre doch denkbar einfach
|
|
SvenAbeln
      
Beiträge: 334
Erhaltene Danke: 3
|
Verfasst: Mi 19.10.11 14:31
Einer Funktion einmal einen Integer und ein anderes mal ein Objekt übergeben, kann niemals ganz sicher funktionieren. Du kannst nur raten was da übergeben wurde. Der Test von bummi prüft zwar ob sich unter der Adresse ein Objekt befindet, aber wollte ich das wirklich übergeben?
z.B. Übergebe ich ein Integer
Delphi-Quelltext
Was passiert aber wenn sich zufällig an der Adresse im Speicher auch ein Objekt befindet?
Wollte ich nun das Objekt übergeben oder doch einfach die Zahl?
|
|
jasocul
      
Beiträge: 6395
Erhaltene Danke: 149
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mi 19.10.11 14:32
Warum kannst du das eigentlich nicht überladen?
|
|
Deerfield 
      
Beiträge: 35
Delphi XE Pro
|
Verfasst: Mi 19.10.11 15:03
Wie man es anders/besser/eigentlich richtig macht, weiß ich doch. Auch vielen Dank für dementsprechende Hinweise.
Ich wollte nur wissen, ob jemand eine Möglichkeit kennt, den Klassentyp eines evtl. angehangenen Objekts zu überprüfen, ich kann mittels TMeinObjekt(aParam) im "Gut-Fall" ja problemlos zugreifen (Objektreferenz), nur wenn halt "nur" ein Integerwert übergeben wird, komme ich wohl um eine abgefangene Exception nicht herum.
|
|
jaenicke
      
Beiträge: 19326
Erhaltene Danke: 1749
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 19.10.11 16:09
Damit ist es aber nicht immer getan. Wenn du den falschen Speicherbereich erwischst, kann es dir passieren, dass dein Programm trotz try..except abstürzt. Einfach weil Windows selbst die Ausführung abbricht, weil du Windows in diesem Adressbereich störst...
Oder weil das Antivirenprogramm aktiv wird...
Ich habe dafür eine Funktion geschrieben, die aber eben auch nicht 100%ig vor einem Absturz bewahrt... Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| function ValidateObj(Obj: TObject): Pointer; var VmtSelf: Pointer; begin if Assigned(Obj) and (Integer(Obj) > $FFFF) and not IsBadReadPtr(Obj, 4) and not IsBadReadPtr(PPointer(Obj)^, 4) then try Result := Obj; VmtSelf := Pointer(Pointer(Integer(Obj.ClassType) + vmtSelfPtr)^); if IsBadReadPtr(VmtSelf, 4) or (Obj.ClassType <> VmtSelf) then Result := nil; except Result := nil; end else Result := nil; end; | Die versucht zu prüfen, ob alle notwendigen Stellen zugreifbar sind und vergleicht im Erfolgsfall die passenden Daten. Denn am Ende der Virtual Method Table steht ein Pointer auf sich selbst. Das kann man ausnutzen um zu prüfen, ob es ein Objekt sein könnte.
Wenn die Funktion nil zurückgibt, ist es kein gültiges Objekt, sonst mit 99,4%iger Wahrscheinlichkeit ein gültiges Objekt.
|
|