Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Prozeduraufruf an "begin" binden?


moklok - Mi 23.09.09 13:57
Titel: Prozeduraufruf an "begin" binden?
Hallo,

habe beim Debuggen (Projekt -> Optionen -> Comiler -> mit Debug-DCUs) festgestellt, dass bei Konstruktoren schon im "begin" eine Prozedur aufgerufen wird:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
constructor TMyClass.Create;
begin // <- hier wird "function _ClassCreate" aufgerufen

  inherited

  // inits
  // ...
end;

Wollte gerne mal fragen, ob ich sowas auch selber machen kann. Sprich eigene Funktionsaufrufe an diese "begins" hängen. Wenn ja, wie geht das?

Vielen Dank im Voraus

moklok

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt


BenBE - Mi 23.09.09 14:32

In der Begin-Zeile wird eine Reihe von Vorbereitungen für den Prozedur-Aufruf (Anlegen von Stackframes, Reservieren mancher lokalen Variablen, ...) ausgeführt. Das ist reine Compiler-Magic.

Man kann nur, wenn man mit ASM arbeitet, diese Initialisierung mit etwas Wissen zu dem, was man da tut, unterdrücken und selbrmachen, kann dann aber wirklich nur in ASM seine Prozedur schreiben.


moklok - Mi 23.09.09 14:41

Hey Danke für die schnelle Antwort...

wie man Funktionen in ASM schreibt ist mir vertraut. Wüßtest du auch, wie man dem Compiler genau sagt, dass meine Funktion z.B. mit jedem Konstruktoraufruf ausgeführt werden soll. Mir ist die Anbindung noch nicht so klar.


moklok


Gausi - Mi 23.09.09 14:55

Mal ne Frage am Rande: Wozu?

Es sollte doch reichen, wenn du im Konstruktor einfach deine Prozedur aufrufst, oder? Und wenn du so massig viele Klassen hast, wo du das alles einfügen willst: Bau dir eine gemeinsame Oberklasse und ruf deine Prozedur in dessen Create auf, dann wird sie auch automatisch über das inherited in den Sub-Klassen aufgerufen.


BenBE - Mi 23.09.09 14:55

Das "hooking" des Prozedur-Startup-Codes (wie es bei vielen Scriptsprachen geht), ist in Delphi so nicht möglich. Hier muss man zur Laufzeit in jeden Prozedur-Kopf einen entsprechenden Aufruf manuell reinpatchen, was das Programm sehr träge und instabil machen kann. Mit der uallCollection ließe sich sowas machen.

Ansonsten stimm ich user profile iconGausi zu ...


moklok - Mi 23.09.09 15:23

Hallo,

das Wozu:

- dachte daran allgemeingültige Funktionalitäten (zumindest allgemeingültig innerhalb meiner Projekte), so direkt an bestimmte Arten von Funktionen (constructor, function, etc...) anzuhängen. Also auch, wenn man nicht objektorientiert arbeitet.

- bin einfach nur neugierig und daran interessiert so ziemlich alle Tricks kennenzulernen und auszuprobieren.

Danke für Teilnahme an diesem Thread. Denke der Thread ist mit dem letzten Beitrag beantwortet.

moklok


Reinhard Kern - Mi 23.09.09 16:02

user profile iconmoklok hat folgendes geschrieben Zum zitierten Posting springen:
- dachte daran allgemeingültige Funktionalitäten (zumindest allgemeingültig innerhalb meiner Projekte), so direkt an bestimmte Arten von Funktionen (constructor, function, etc...) anzuhängen. Also auch, wenn man nicht objektorientiert arbeitet.


Hallo,

hab ich auch mal mit experimentiert, als ich noch Pascal-Compiler ohne OO hatte, hat sich mit OO aber erledigt. Man sollte auch nicht versuchen, auf 2 verschiedenen Schienen Vererbung zu realisieren, das gibt irgendwann Verwirrung. Also OO und alles wird gut.

Gruss Reinhard


delfiphan - Do 24.09.09 21:55

Du kannst die Instructions an der Einsprungadresse einer Prozedur durch ein Jump ersetzen (entsprechend musst du diese Befehle später wieder ausführen und zurückspringen), viel mehr fällt mir jetzt auch nicht ein.

Sowas würde ich aber nur im absoluten Notfall machen. Wenn du z.B. einen Bug in einer Third-Party Komponente findest und du die Sources dazu nicht hast. Es gibt an vielen Stellen Prozeduraufrufe, auch wenn dies im Code nicht direkt ersichtlich ist. Das sind Details der RTL und braucht dich nicht zu interessieren.

Edit: Vermutlich hat das BenBE schon erwähnt (weiss nicht, ob ich ihn richtig verstanden habe). Wenn man das sauber macht dürfte das keine Schwierigkeiten machen und von der Performance her dürfte es auch nicht so wahnsinnig schlimm sein.


BenBE - Do 24.09.09 23:05

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Du kannst die Instructions an der Einsprungadresse einer Prozedur durch ein Jump ersetzen (entsprechend musst du diese Befehle später wieder ausführen und zurückspringen), viel mehr fällt mir jetzt auch nicht ein.

Das ist im Detail, wenn man das richtig machen möchte gar nicht so einfach, wie sich das anhört, da man den gesamten Befehlssatz nicht nur erkennen, sondern auch behandeln können muss. Durch das Verschieben eines Befehls im Speicher können nämlich indirekte Zugriffe und Sprünge ganz schnell ihr Ziel verändern.

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Sowas würde ich aber nur im absoluten Notfall machen. Wenn du z.B. einen Bug in einer Third-Party Komponente findest und du die Sources dazu nicht hast. Es gibt an vielen Stellen Prozeduraufrufe, auch wenn dies im Code nicht direkt ersichtlich ist. Das sind Details der RTL und braucht dich nicht zu interessieren.

Sollte einen auch erstmal nicht, da sich um diese Details der Kompiler bereits in wesentlichen Teilen kümmert.

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Edit: Vermutlich hat das BenBE schon erwähnt (weiss nicht, ob ich ihn richtig verstanden habe). Wenn man das sauber macht dürfte das keine Schwierigkeiten machen und von der Performance her dürfte es auch nicht so wahnsinnig schlimm sein.

Jap, genau sowas hatte ich bereits angedeutet und darauf bezog sich auch mein Hinweis, dass das i.d.R. sehr Wacklig gebaut ist. Z.B. wenn man solche Patches in einer Multi-Thread-Umgebung baut (oder mit Fibers ;-)) Genauso muss man die Opcodes korrekt behandeln ... Wer versucht, sowas mal eben aus dem Ärmel zu schütteln, wird an solchen Dingen nicht viel Freude haben. Das Debug Interface von Omorphia hat z.B. zum Abfangen von Exceptions eine ähnliche Technik genutzt (IAT-Hooks), wobei die Fehler dabei von funktionierte nicht, über Programm schmiert trotz Patch weg bis hin zu Stack-Overflow wegen rekursiver Exceptions führte ... Sowas in der IDE drinnen hängen haben und man freut sich ;-)


moklok - Mo 19.10.09 13:54

Wow, danke nochmal an alle für die Teilnahme am Thread :D .