AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Ist im Prozedurzeiger eine Klasse drin?

Ein Thema von himitsu · begonnen am 4. Feb 2011 · letzter Beitrag vom 4. Feb 2011
Antwort Antwort
Benutzerbild von himitsu
himitsu

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

Ist im Prozedurzeiger eine Klasse drin?

  Alt 4. Feb 2011, 11:10
Delphi-Version: XE
Ja ja, ich mit meinen komischen Fragen ... ach ja, Moin erstma.


Kann man irgendwie rausbekommen, ob in einer type T = procedure(...) of object; ein Zeiger auf eine Methode+Objektinstanz oder eine Klassenmethode+Klassenzeiger drinsteckt?

Delphi-Quellcode:
type
  TProc = procedure of object;
  TTest = class
    procedure A;
    class procedure B;
  end;

var
  X: TProc;
  O: TTest;

X := O.A;
X := TTest.B;
Beides ist ja möglich.

Zwecks Threadsicherheit würde ich gern einen Clone des Objekts erstellen, wenn ein Objekt drin ist, ansonsten direkt aufrufen.

Also irgendwas in dieser Richtung vielleicht?
Delphi-Quellcode:
if TMethod(X).Data is TClass then ...
if TMethod(X).Data is TObject then ...


[add]
Hier laufe ich (zufällig) jeweils, beim Test auf's Andere, in eine Exception
und auf Exceptions möchte ich gerne verzichten.
Delphi-Quellcode:
type
  TProc = procedure of object;
  TTest = class
    procedure A;
    class procedure B;
  end;

procedure TTest.A;
begin
end;

class procedure TTest.B;
begin
end;

procedure Check(Proc: TProc);
begin
  try
    if TObject(TMethod(Proc).Data) is TTest then
      Beep;
  except
  end;
  try
    if TClass(TMethod(Proc).Data).InheritsFrom(TTest) then
      Beep;
  except
  end;
end;

procedure TForm2.FormCreate(Sender: TObject);
var
  X: TProc;
  O: TTest;
begin
  O := TTest.Create;
  X := O.A;
  Check(X);
  O.Free;

  X := TTest.B;
  Check(X);
end;
$2B or not $2B

Geändert von himitsu ( 4. Feb 2011 um 11:26 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von guinnes
guinnes

Registriert seit: 28. Feb 2007
Ort: Bottrop
265 Beiträge
 
Delphi 5 Enterprise
 
#2

AW: Ist im Prozedurzeiger eine Klasse drin?

  Alt 4. Feb 2011, 12:46
Hast du mal gekuckt, ob bei einer Class-Procedure Data nicht einfach nur NIL ist ?
Glückauf
  Mit Zitat antworten Zitat
WM_CLOSE

Registriert seit: 12. Mai 2010
Ort: königsbronn
398 Beiträge
 
RAD-Studio 2009 Pro
 
#3

AW: Ist im Prozedurzeiger eine Klasse drin?

  Alt 4. Feb 2011, 12:57
@guinnes: Es ist nicht nil, aber auch keine Instanz, aber z.b.auf InstanceSize kann man zugreifen. Interressant

Edit: klar, ist auch eine class function

Geändert von WM_CLOSE ( 4. Feb 2011 um 13:01 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von guinnes
guinnes

Registriert seit: 28. Feb 2007
Ort: Bottrop
265 Beiträge
 
Delphi 5 Enterprise
 
#4

AW: Ist im Prozedurzeiger eine Klasse drin?

  Alt 4. Feb 2011, 13:23
Es ist nicht nil,
Ich habs nicht probiert, aber da in Data ein Zeiger auf die Instanz steht und es die bei einer Class Procedure aber nicht gibt, sollte da konsequenterweise NIL drin stehen
Zitat:
aber z.b.auf InstanceSize kann man zugreifen. Interressant
Dafür brauchst du ja auch keine Instanz
Glückauf
  Mit Zitat antworten Zitat
Benutzerbild von guinnes
guinnes

Registriert seit: 28. Feb 2007
Ort: Bottrop
265 Beiträge
 
Delphi 5 Enterprise
 
#5

AW: Ist im Prozedurzeiger eine Klasse drin?

  Alt 4. Feb 2011, 13:35
Ich habs mir mal angeschaut :
Im Falle einer normalen Methode steht in Data die Instanz, im Falle der Class Procedure steht in Data ein Zeiger auf die VMT.
Also : Beim Start feststellen, wo der Heap anfängt, ist der Zeiger in Data kleiner, ist es eine Class Procedure
Glückauf
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Ist im Prozedurzeiger eine Klasse drin?

  Alt 4. Feb 2011, 13:48
Bei einer Methode ist in Data ein Zeiger auf die Objektinstanz drin (TObject),
wärend bei der Klassen-Methode ein Zeiger auf die Klasse drin steht.

In diesem .Code steht das drin, welches an den versteckten "Self" Parameter übergeben wird.
Methode: Self = Instanz
Klassen-Methode: Self = Klasse, über welche auf die Methode zugegriffen wurde.
(bei der Objektinstanz wird der Zeiger auf die interne Klasse ja in der Instanz gespeichert)

Delphi-Quellcode:
type
  TTest = class
    class procedure Proc;
  end;
  TTest2 = class(TTest)
  end;

class procedure TTest.Proc;
begin
  ShowMessage({Self.}ClassName);
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  TTest.Proc;
  TTest2.Proc;
end;
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von guinnes
guinnes

Registriert seit: 28. Feb 2007
Ort: Bottrop
265 Beiträge
 
Delphi 5 Enterprise
 
#7

AW: Ist im Prozedurzeiger eine Klasse drin?

  Alt 4. Feb 2011, 14:11
Nicht schön tut aber :
Delphi-Quellcode:
procedure Check(Proc: TProc);
begin
  if Integer(TMethod(Proc).Data) > Integer(Application) then
    ShowMessage('Object')
  else
    ShowMessage('Class Proc');
end;
Glückauf
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Ist im Prozedurzeiger eine Klasse drin?

  Alt 4. Feb 2011, 14:37
Das geht aber nur, da der Speicher der Application-Instanz zufällig hinter dem Programmcode und der Speicher für die zu testende Instanz zufällig hinter der Application.Instanz im "RAM" liegt ... davor ist aber auch noch genug Platz.

Hab jetzt erstmal das hinbekommen.
(Zum Glück sollte es sich bei mir immer um gültige Klassenzeiger oder Objektinstanzen handeln.)
Delphi-Quellcode:
var
  P, P2: Pointer;
  C: LongWord;
  X: array[1..vmtCreateObject - vmtSelfPtr] of Byte;
  Proc: procedure of object;

// IsClass(TTest)
P := PAnsiChar(TMethod(Proc).Data) + vmtSelfPtr;
if (ReadProcessMemory(GetCurrentProcess, P, @X, SizeOf(X), C))
    and (C = SizeOf(X)) and (PPointer(P)^ = TMethod(Proc).Data)
    and (TClass(TMethod(Proc).Data).InheritsFrom(TTest)) then
  Beep;

// IsObject(TTest)
P := TMethod(Proc).Data;
if ReadProcessMemory(GetCurrentProcess, P, @X, SizeOf(Pointer), C) and (C = SizeOf(Pointer)) then begin
  P2 := PPointer(P)^;
  P := PAnsiChar(P2) + vmtSelfPtr;
  if ReadProcessMemory(GetCurrentProcess, P, @X, SizeOf(X), C)
      and (C = SizeOf(X)) and (PPointer(P)^ = P2)
      and (TObject(TMethod(Proc).Data) is TTest) then
    Beep;
end;

//ReadProcessMemory als Ersatz für IsBadReadPtr
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von guinnes
guinnes

Registriert seit: 28. Feb 2007
Ort: Bottrop
265 Beiträge
 
Delphi 5 Enterprise
 
#9

AW: Ist im Prozedurzeiger eine Klasse drin?

  Alt 4. Feb 2011, 14:51
Das geht aber nur, da der Speicher der Application-Instanz zufällig hinter dem Programmcode und der Speicher für die zu testende Instanz zufällig hinter der Application.Instanz im "RAM" liegt ... davor ist aber auch noch genug Platz.
Da das Application-Object ja relativ früh in einem noch recht unfragmentierten Speicher angelegt wird, ist die Wahrscheinlichkeit recht hoch, dass es ziemlich am Anfang des Heaps liegt. Aber im Prinzip hast du recht
Um dem aus dem Weg zu gehen, kann man die Adresse der globalen Variablen Application benutzen : Die liegt unterhalb des Heap aber garantiert höher als die VMT's :
Delphi-Quellcode:
procedure Check(Proc: TProc);
begin
  if Integer(TMethod(Proc).Data) < Integer(@Application) then
    ShowMessage('Class Proc')
  else
    ShowMessage('Object');
end;
Glückauf

Geändert von guinnes ( 4. Feb 2011 um 20:13 Uhr) Grund: Rächtschraibfähler besaitigt
  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 04:32 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