| Autor |
Beitrag |
opfer.der.genauigkeit
      
Beiträge: 754
Erhaltene Danke: 1
|
Verfasst: Fr 11.03.05 14:29
Hi,
Ich bräuchte eine tech. Refferenz (wenn möglich) und vielleicht ein paar Antworten auf folgendes:
Ein neues Projekt mit Delphi.
1. Das Projekt ist eine normale Anwendung. (Unit1, TForm1: TForm)
2. Dem Projekt füge ich ein zweites Formular hinzu. (Unit2, TForm2: TForm)
3. Aus Unit2 entferne ich "var Form2: TForm"
4. Unter Projektoptionen wird Form2 aus den auto. generierten Formularen rausgeschmissen.
5. Der Klassendefinition TForm2 füge ich im public Abschnitt diese Funktion hinzu:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| type .. public procedure MyMessage; .. implementation .. procedure TForm2.MyMessage; begin ShowMessage('test'); end; |
5. In Unit1 füge ich unter implementation die uses- Klausel hinzu und dort Unit2.
6. Ich plazier nen Button auf das Formular "Form1" und mach folgendes:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| procedure TForm1.OnButtonClick(Sender); begin asm call TForm2.MyMessage; end; end; |
7. Compilieren und Ausführen. Alles funktioniert. (ich hoffe in der Anleitung fehlt jetzt nix.  )
Delphi scheint hier im Speicher schon ein Abbild der Klasse TForm2 abzulegen, sonst wäre der Aufruf nicht möglich oder wie
sieht das im Detail aus?
Ich dachte immer Klassen werden erst dann auf dem Speicher abgebildet wenn die erste Instanz erzeugt wurde.
(IMHO teilen sich ja alle Objekte den Speicher für die Methoden [nicht aber die Properties] also bedarf es
ja nur eines Abbildes und die Objekte greifen dann sequentiell zu oder  )
Also, wann befindet sich das Klassenabbild auf dem Heap?
Und gibt es einen alternativen Aufruf anstelle der Assembleranweisung?
z.B. über API?
(Danke an alle die dazu was sagen können  )
_________________ Stellen Sie sich bitte Zirkusmusik vor.
|
|
AXMD
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Fr 11.03.05 14:31
Das hat meiner Meinung nach wenig mit Speicherverwaltung zu tun. Du hast wahrscheinlich Unit2 noch immer in der Uses-Klausel
AXMD
|
|
opfer.der.genauigkeit 
      
Beiträge: 754
Erhaltene Danke: 1
|
Verfasst: Fr 11.03.05 14:33
AXMD hat folgendes geschrieben: | Das hat meiner Meinung nach wenig mit Speicherverwaltung zu tun. Du hast wahrscheinlich Unit2 noch immer in der Uses-Klausel
AXMD |
Ja, hab ich doch geschrieben, daß ich sie in Unit1 hinzufüge.
Aber es wird nirgendwo eine Instanz von TForm2 erzeugt. Deshalb die Frage wie Delphi das Handhabt, daß so ein Aufruf möglich ist.
_________________ Stellen Sie sich bitte Zirkusmusik vor.
|
|
AXMD
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Fr 11.03.05 14:34
opfer.der.genauigkeit hat folgendes geschrieben: | AXMD hat folgendes geschrieben: | Das hat meiner Meinung nach wenig mit Speicherverwaltung zu tun. Du hast wahrscheinlich Unit2 noch immer in der Uses-Klausel
AXMD |
Ja, hab ich doch geschrieben, daß ich sie in Unit1 hinzufüge. |
Wieso wundert dich das dann? Ist doch klar, dass er es kennt, wenn du es in der uses hast und damit mitkompilierst.
AXMD
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Fr 11.03.05 14:41
Du musst 2 Sachen trennen - die Instanz einer Klasse mit ihren Feldern und andrerseit die Methoden der Klasse. Die Instanz existiert nur wenn sie erstellt wird, die Methoden sind aber immer im Speicher. Es ist ja schließlich auch nicht so, dass jede Instanz ihre eigenen Methoden hat, sondern der Code der Methoden wird von allen Instanzen einer Klasse gemeinsam benutzt. Es wird intern nur eine Referenz auf das Objekt mitgegeben, von dem aus die Methode aufgerufen wurde. Diese Referenz ist innerhalb der Methode als "Self" verfügbar. Greift man innerhalb der Methode auf irgendwelche Objekt-Felder zu, so wird immer nur auf die Felder des Ojekts zugegriffen, dass per Self referenziert wird.
Du hast in deinem Code nur eine MessageBox, welche einen Text ausgibt - unabhängig von jeder TForm2-Instanz.. wenn du stattdessen irgendeinen Code hast, der auf Felder von TForm2 zugreifst wirst du eine nette EAV erhalten..!
Gruß, Motzi
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
AXMD
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Fr 11.03.05 14:43
Motzi hat folgendes geschrieben: | Du musst 2 Sachen trennen - die Instanz einer Klasse mit ihren Feldern und andrerseit die Methoden der Klasse. Die Instanz existiert nur wenn sie erstellt wird, die Methoden sind aber immer im Speicher. Es ist ja schließlich auch nicht so, dass jede Instanz ihre eigenen Methoden hat, sondern der Code der Methoden wird von allen Instanzen einer Klasse gemeinsam benutzt. Es wird intern nur eine Referenz auf das Objekt mitgegeben, von dem aus die Methode aufgerufen wurde. Diese Referenz ist innerhalb der Methode als "Self" verfügbar. Greift man innerhalb der Methode auf irgendwelche Objekt-Felder zu, so wird immer nur auf die Felder des Ojekts zugegriffen, dass per Self referenziert wird.
Du hast in deinem Code nur eine MessageBox, welche einen Text ausgibt - unabhängig von jeder TForm2-Instanz.. wenn du stattdessen irgendeinen Code hast, der auf Felder von TForm2 zugreifst wirst du eine nette EAV erhalten..!
Gruß, Motzi |
Ach so hat er das gemeint
AXMD
|
|
opfer.der.genauigkeit 
      
Beiträge: 754
Erhaltene Danke: 1
|
Verfasst: Fr 11.03.05 14:51
AXMD hat folgendes geschrieben: | opfer.der.genauigkeit hat folgendes geschrieben: | AXMD hat folgendes geschrieben: | Das hat meiner Meinung nach wenig mit Speicherverwaltung zu tun. Du hast wahrscheinlich Unit2 noch immer in der Uses-Klausel
AXMD |
Ja, hab ich doch geschrieben, daß ich sie in Unit1 hinzufüge. |
Wieso wundert dich das dann? Ist doch klar, dass er es kennt, wenn du es in der uses hast und damit mitkompilierst.
AXMD |
Ich hab gesagt, daß mich das wundert? Wüßt ich von.
Hab glaub ich nach dem Wie gefragt, also was passiert.
Also liegt es an dem Eintrag in der Uses? Gut zu wissen.
Motzi hat folgendes geschrieben: | Du musst 2 Sachen trennen - die Instanz einer Klasse mit ihren Feldern und andrerseit die Methoden der Klasse. Die Instanz existiert nur wenn sie erstellt wird, die Methoden sind aber immer im Speicher. Es ist ja schließlich auch nicht so, dass jede Instanz ihre eigenen Methoden hat, sondern der Code der Methoden wird von allen Instanzen einer Klasse gemeinsam benutzt. Es wird intern nur eine Referenz auf das Objekt mitgegeben, von dem aus die Methode aufgerufen wurde. Diese Referenz ist innerhalb der Methode als "Self" verfügbar. Greift man innerhalb der Methode auf irgendwelche Objekt-Felder zu, so wird immer nur auf die Felder des Ojekts zugegriffen, dass per Self referenziert wird.
Du hast in deinem Code nur eine MessageBox, welche einen Text ausgibt - unabhängig von jeder TForm2-Instanz.. wenn du stattdessen irgendeinen Code hast, der auf Felder von TForm2 zugreifst wirst du eine nette EAV erhalten..!
Gruß, Motzi |
opfer.der.genauigkeit hat folgendes geschrieben: |
Delphi scheint hier im Speicher schon ein Abbild der Klasse TForm2 abzulegen, sonst wäre der Aufruf nicht möglich oder wie
sieht das im Detail aus?
|
Richtig.
opfer.der.genauigkeit hat folgendes geschrieben: |
Ich dachte immer Klassen werden erst dann auf dem Speicher abgebildet wenn die erste Instanz erzeugt wurde.
|
Falsch, es reicht wenn die Klasse mit einkompiliert wurde.
opfer.der.genauigkeit hat folgendes geschrieben: |
(IMHO teilen sich ja alle Objekte den Speicher für die Methoden [nicht aber die Properties] also bedarf es
ja nur eines Abbildes und die Objekte greifen dann sequentiell zu oder )
|
Richtig.
opfer.der.genauigkeit hat folgendes geschrieben: |
Und gibt es einen alternativen Aufruf anstelle der Assembleranweisung?
z.B. über API?
|
Darauf ne Antwort wäre noch ganz brauchbar.
Thx bis jetzt für die Infos.
_________________ Stellen Sie sich bitte Zirkusmusik vor.
|
|
wdbee
      
Beiträge: 628
Erhaltene Danke: 1
|
Verfasst: Fr 11.03.05 15:14
Definiere eine Klassenfunktion:
In einer Klassenfunktion gibt es den oben angeführten, verstecketen Zeiger self nicht. Darum kann man alles machen, was ohne den in deinem Fall nicht definierten Bezug zu einer Instanz möglich ist. Also kann die Variabe InstanzVariable nicht verwendet werden, die UnitVariable dagegen schon;
Eine Klassenfunktion wird so definiert
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| type TMyClass = class ... InstanzVariable: Integer; class procedure TMyClass.MyProcedure; ... end; ... var UnitVariable: Integer; ... class procedure TMyClass.MyProcedure; begin ShowMessage('Mein Text!'); end; |
und kann ohne Instanz folgendermaßen aufgerufen werden:
Delphi-Quelltext
|
|
opfer.der.genauigkeit 
      
Beiträge: 754
Erhaltene Danke: 1
|
Verfasst: Fr 11.03.05 15:28
wdbee hat folgendes geschrieben: | Definiere eine Klassenfunktion:
In einer Klassenfunktion gibt es den oben angeführten, verstecketen Zeiger self nicht. Darum kann man alles machen, was ohne den in deinem Fall nicht definierten Bezug zu einer Instanz möglich ist. Also kann die Variabe InstanzVariable nicht verwendet werden, die UnitVariable dagegen schon;
Eine Klassenfunktion wird so definiert
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| type TMyClass = class ... InstanzVariable: Integer; class procedure TMyClass.MyProcedure; ... end; ... var UnitVariable: Integer; ... class procedure TMyClass.MyProcedure; begin ShowMessage('Mein Text!'); end; |
und kann ohne Instanz folgendermaßen aufgerufen werden:
Delphi-Quelltext |
Ja, ich weiß, das ist auch garnicht meine Frage bzw. wurde das ja schon "nochmal" geklärt, was ich am Anfang gesagt hab.
Das geht sogar noch viel einfacher.
Nochmal: Ich wollte wissen unter welcher Bedingung die Klasse auf dem Speicher abgebildet wird.
Und jetzt wurde gesagt, es läge daran, daß die Unit2 in die Uses eingetragen wurde und somit einkompiliert wird.
Das glaub ich jetzt mal so weit. *g*
//Edit:
opfer.der.genauigkeit hat folgendes geschrieben: |
Und gibt es einen alternativen Aufruf anstelle der Assembleranweisung?
z.B. über API?
|
Vergeßt diese Frage bitte. Ich steh grad neben mir. oO
_________________ Stellen Sie sich bitte Zirkusmusik vor.
|
|
wdbee
      
Beiträge: 628
Erhaltene Danke: 1
|
Verfasst: Fr 11.03.05 15:34
opfer.der.genauigkeit hat folgendes geschrieben: | Und gibt es einen alternativen Aufruf anstelle der Assembleranweisung?
z.B. über API?
|
Das mit der Klassenfunktion bezog sich doch auf die Zusatzfrage 
|
|
opfer.der.genauigkeit 
      
Beiträge: 754
Erhaltene Danke: 1
|
Verfasst: Fr 11.03.05 15:37
wdbee hat folgendes geschrieben: | opfer.der.genauigkeit hat folgendes geschrieben: | Und gibt es einen alternativen Aufruf anstelle der Assembleranweisung?
z.B. über API?
|
Das mit der Klassenfunktion bezog sich doch auf die Zusatzfrage  |
Ja, danke hab ja noch meinen Eintrag editiert.
Ich bin grad wirklich total verpeilt.
Hast recht mit dem was du geschrieben hast.
//Edit:
Achja, es reicht im übrigen, wenn man die Funktion public deklariert und dann den Aufruf so gestalltet.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| procedure TForm1.Button1Click(Sender: TObject); var p: pointer; begin p := pointer(TForm2); TForm2(p).MyMEssage; end; |
_________________ Stellen Sie sich bitte Zirkusmusik vor.
|
|
UC-Chewie
      
Beiträge: 531
WinXP
D5 Ent
|
Verfasst: Fr 11.03.05 15:53
opfer.der.genauigkeit hat folgendes geschrieben: | | Nochmal: Ich wollte wissen unter welcher Bedingung die Klasse auf dem Speicher abgebildet wird. |
Was verstehst du unter "abgebildet"?
Eine Klasse ist theoretisch erstmal nur ein Bauplan für Objekte, ist also nur ein Konzept, keine Entität im fertigen Programm.
Soweit die Theorie. Praktisch wird aus naheliegenden Gründen schon was von der Klasse im Kompilat zu finden sein:
- die VMT
- die Methoden (ob Klassenmethode oder Instanzmethode spielt keine Rolle)
- evtl. mehr
So, jetzt die Frage: Wann (d.h. unter welchen Umständen) kommen diese Teile in das Kompilat?
Antwort: Sobald der Compiler auf die Deklaration der Klasse stößt. Der Compiler kann nicht erkennen, ob die Klasse wirklich verwendet wird (glaub ich zumindest), da die Klasse auch infolge einer ClassFactory benutzt werden kann. Also
_________________ Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
|
|
opfer.der.genauigkeit 
      
Beiträge: 754
Erhaltene Danke: 1
|
Verfasst: Fr 11.03.05 16:04
UC-Chewie hat folgendes geschrieben: | opfer.der.genauigkeit hat folgendes geschrieben: |
Eine Klasse ist theoretisch erstmal nur ein Bauplan für Objekte, ist also nur ein Konzept, keine Entität im fertigen Programm.
|
|
Ich glaube ich würde nicht solche Topics hier reinstellen, wenn mir das nicht klar wäre.
UC-Chewie hat folgendes geschrieben: |
So, jetzt die Frage: Wann (d.h. unter welchen Umständen) kommen diese Teile in das Kompilat?
Antwort: Sobald der Compiler auf die Deklaration der Klasse stößt. Der Compiler kann nicht erkennen, ob die Klasse wirklich verwendet wird (glaub ich zumindest), da die Klasse auch infolge einer ClassFactory benutzt werden kann. Also
|
Also mit dem Uses - Eintrag.
Aber einen Begriff find ich gut ClassFactory.
Was'n das?
_________________ Stellen Sie sich bitte Zirkusmusik vor.
|
|
wdbee
      
Beiträge: 628
Erhaltene Danke: 1
|
Verfasst: Sa 12.03.05 10:41
opfer.der.genauigkeit hat folgendes geschrieben: |
Aber einen Begriff find ich gut ClassFactory.
Was'n das? |
COM verwendet die IClassFactory-Schnittstelle um den Bauplan eines COM-Objektes abzurufen. Die Class Factory erstellt dann eine Instanz des Objekttyps. Der Anstoss, ein Objekt zu erzeugen, kann deshalb auch von außen kommen, weswegen die Klassenmethoden usw. im Programm enthalten sein müssen, auch wenn keine Instanz im Programm selbst erzeugt wird.
|
|