Autor Beitrag
opfer.der.genauigkeit
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754
Erhaltene Danke: 1



BeitragVerfasst: 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:

ausblenden 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:
ausblenden 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. 8) )

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 :D )

_________________
Stellen Sie sich bitte Zirkusmusik vor.
AXMD
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754
Erhaltene Danke: 1



BeitragVerfasst: Fr 11.03.05 14:33 
user profile iconAXMD 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Fr 11.03.05 14:34 
user profile iconopfer.der.genauigkeit hat folgendes geschrieben:
user profile iconAXMD 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Fr 11.03.05 14:43 
user profile iconMotzi 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 :autsch:

AXMD
opfer.der.genauigkeit Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754
Erhaltene Danke: 1



BeitragVerfasst: Fr 11.03.05 14:51 
user profile iconAXMD hat folgendes geschrieben:
user profile iconopfer.der.genauigkeit hat folgendes geschrieben:
user profile iconAXMD 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. :lol:
Hab glaub ich nach dem Wie gefragt, also was passiert.

Also liegt es an dem Eintrag in der Uses? Gut zu wissen. :wink:



user profile iconMotzi 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



user profile iconopfer.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.

user profile iconopfer.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.

user profile iconopfer.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.

user profile iconopfer.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. :D

Thx bis jetzt für die Infos.

_________________
Stellen Sie sich bitte Zirkusmusik vor.
wdbee
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 628
Erhaltene Danke: 1



BeitragVerfasst: 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
ausblenden 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:
ausblenden Delphi-Quelltext
1:
  TMyClass.MyProcedure;					
opfer.der.genauigkeit Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754
Erhaltene Danke: 1



BeitragVerfasst: Fr 11.03.05 15:28 
user profile iconwdbee 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
ausblenden 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:
ausblenden Delphi-Quelltext
1:
  TMyClass.MyProcedure;					


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:

user profile iconopfer.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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 628
Erhaltene Danke: 1



BeitragVerfasst: Fr 11.03.05 15:34 
user profile iconopfer.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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754
Erhaltene Danke: 1



BeitragVerfasst: Fr 11.03.05 15:37 
user profile iconwdbee hat folgendes geschrieben:
user profile iconopfer.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. :roll:
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.

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 531

WinXP
D5 Ent
BeitragVerfasst: Fr 11.03.05 15:53 
user profile iconopfer.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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754
Erhaltene Danke: 1



BeitragVerfasst: Fr 11.03.05 16:04 
user profile iconUC-Chewie hat folgendes geschrieben:
user profile iconopfer.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. :gruebel:


user profile iconUC-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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 628
Erhaltene Danke: 1



BeitragVerfasst: Sa 12.03.05 10:41 
user profile iconopfer.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.