AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Methode "Free" selbst implementieren (Assembler-Problem?)
Thema durchsuchen
Ansicht
Themen-Optionen

Methode "Free" selbst implementieren (Assembler-Problem?)

Ein Thema von VizeTE · begonnen am 22. Feb 2005 · letzter Beitrag vom 15. Mär 2005
Antwort Antwort
Seite 3 von 5     123 45      
Benutzerbild von retnyg
retnyg

Registriert seit: 11. Feb 2005
193 Beiträge
 
#21

Re: Methode "Free" selbst implementieren (Assemble

  Alt 22. Feb 2005, 15:44
dann halt so:
Delphi-Quellcode:
procedure dosomething;
begin
  mydestroyvariable := true;
end;

procedure TObject.Free(myparam:boolean); stdcall;
asm
        pop edx
        cmp edx, 1
        jne @@weiter
        call dosomething
@@weiter:
        TEST EAX,EAX
        JE @@exit
        MOV ECX,[EAX]
        CALL dword ptr [ECX].vmtDestroy
@@exit:
end;
  Mit Zitat antworten Zitat
Benutzerbild von MaBuSE
MaBuSE

Registriert seit: 23. Sep 2002
Ort: Frankfurt am Main (in der Nähe)
1.837 Beiträge
 
Delphi 10 Seattle Enterprise
 
#22

Re: Methode "Free" selbst implementieren (Assemble

  Alt 22. Feb 2005, 15:49
Folgendes "einfaches" Beispiel sollte Dein Problem lösen:

Unit1.pas
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

type
  TMyObject = class;

  TMyObject = class(TForm)
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private-Deklarationen }
    MyRefCount: Integer;
  public
    { Public-Deklarationen }
    constructor Create(AOwner: TComponent); override;
    function GetMyObject: TMyObject;
    procedure FreeMyObject;
  end;

var
  MyObject: TMyObject;

implementation

{$R *.dfm}

{ TMyObject}

// Hier wird nur MyRefCount hochgezählt (auf 1 gesetzt)
constructor TMyObject.Create(AOwner: TComponent);
begin
  inherited;
  Inc(MyRefCount);
end;

// hiermit werden die Objekte freigegeben
procedure TMyObject.FreeMyObject;
begin
  if Self <> nil then
  begin
    Dec(MyRefCount);
    if MyRefCount < 1 then Self.Free;
  end;
end;

// hiermit wird eine Objektreferenz geholt
function TMyObject.GetMyObject: TMyObject;
begin
  if Self <> nil then
  begin
    Inc(MyRefCount);
    Result := Self;
  end
  else
  begin
    Result := nil;
  end;
end;

// Der Timer ist nur auf dem Form, damit man sieht wie viele Refs es gibt
procedure TMyObject.Timer1Timer(Sender: TObject);
begin
  Caption := IntToStr(MyRefCount);
end;

end.
Hier werden 3 wichtige Dinge implementiert:
  • Create wird überladen der der Referenzzähler auf 1 gesetzt
  • Mit GetMyObject wird das akive Object übergeben und der Referenzzähler um 1 erhöht
  • Mit FreeMyObject wird die aktive Referenz freigegeben und der Referenzzähler um 1 erniedrigt
Anwendung siehe Unit2:
Delphi-Quellcode:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    Button6: TButton;
    Button7: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;

implementation

uses Unit1;

{$R *.dfm}

var a, b : TMyObject;

procedure TForm2.Button1Click(Sender: TObject);
begin
  MyObject := TMyObject.Create(self);
  MyObject.Show;
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
  a := MyObject.GetMyObject;
end;

procedure TForm2.Button3Click(Sender: TObject);
begin
  b := MyObject.GetMyObject;
end;

procedure TForm2.Button4Click(Sender: TObject);
begin
  a.FreeMyObject;
  a := nil;
end;

procedure TForm2.Button5Click(Sender: TObject);
begin
  b.FreeMyObject;
  b := nil;
end;

procedure TForm2.Button6Click(Sender: TObject);
begin
  MyObject.FreeMyObject;
  MyObject := nil
end;

procedure TForm2.Button7Click(Sender: TObject);
begin
  Close;
end;

end.
Die Unit 2 ist ein leeres TForm mit 7 TButtons
  • Button1 = MyObject erzeugen und anzeigen
  • Buttin2 = MyObject wird A zugewiesen
  • Buttin3 = MyObject wird B zugewiesen
  • Buttin4 = A wird freigegeben
  • Buttin5 = B wird freigegeben
  • Buttin6 = MyObject wird freigegeben
  • Button7 = Programmende
Egal in welcher Reihenfolge freigegeben wird, verschwindet das Fenster TMyObject erst, wenn die letzte Referenz freigegeben wurde.

Das Ganze wird in die Project1.dpr eingebunden:
Delphi-Quellcode:
program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas{MyObject},
  Unit2 in 'Unit2.pas{Form2};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.
Viel Spaß

[edit]
wichtig: Es muß natürlich erst der Button1 gedrückt werden, damit TMyObject.Create aufgerufen wird.
[/edit]
(°¿°) MaBuSE - proud to be a DP member
(°¿°) MaBuSE - proud to be a "Rüsselmops" ;-)
  Mit Zitat antworten Zitat
VizeTE

Registriert seit: 31. Dez 2002
178 Beiträge
 
Delphi 5 Enterprise
 
#23

Re: Methode "Free" selbst implementieren (Assemble

  Alt 23. Feb 2005, 08:14
Zitat von MaBuSE:
Egal in welcher Reihenfolge freigegeben wird, verschwindet das Fenster TMyObject erst, wenn die letzte Referenz freigegeben wurde.
Das ist ja mal ein ganz anderer Ansatz, sehr interessant. Da muß ich mal d'rüber nachdenken ob ich das auf meine Problemstellung anwenden kann. Aber auf jeden Fall erstmal vielen Dank für deine Mühe!
  Mit Zitat antworten Zitat
Benutzerbild von MaBuSE
MaBuSE

Registriert seit: 23. Sep 2002
Ort: Frankfurt am Main (in der Nähe)
1.837 Beiträge
 
Delphi 10 Seattle Enterprise
 
#24

Re: Methode "Free" selbst implementieren (Assemble

  Alt 23. Feb 2005, 08:52
Zitat von VizeTE:
Zitat von MaBuSE:
Egal in welcher Reihenfolge freigegeben wird, verschwindet das Fenster TMyObject erst, wenn die letzte Referenz freigegeben wurde.
Das ist ja mal ein ganz anderer Ansatz, sehr interessant. Da muß ich mal d'rüber nachdenken ob ich das auf meine Problemstellung anwenden kann. Aber auf jeden Fall erstmal vielen Dank für deine Mühe!
Das ist nur ein einfacher Ansatz. Das lässt sich natürlich auch noch beliebig ausbauen.

Bei .net gibt’s den GarbageCollector, der macht so was Ähnliches. (Nur viel komplizierter )
Wenn es auf ein Objekt keine Referenz mehr gibt, dann wird es in die "Müllsammlung" gegeben und irgendwann später aus dem Speicher entfernt. Aber solange es mindestens eine Referenz gibt, bleibt es im Speicher.
(°¿°) MaBuSE - proud to be a DP member
(°¿°) MaBuSE - proud to be a "Rüsselmops" ;-)
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.481 Beiträge
 
Delphi 10.1 Berlin Professional
 
#25

Re: Methode "Free" selbst implementieren (Assemble

  Alt 23. Feb 2005, 09:34
Zitat von VizeTE:
Wegen einem Free sieht man ja, wie gesagt, nicht extra in die Dokumentation.
Genau. Und was passiert wenn man dein Objekt in eine TObject Referenz steckt? Dann wird bei obj.Free das TObject.Free aufgerufen und nicht deine neue Version.
  Mit Zitat antworten Zitat
VizeTE

Registriert seit: 31. Dez 2002
178 Beiträge
 
Delphi 5 Enterprise
 
#26

Re: Methode "Free" selbst implementieren (Assemble

  Alt 23. Feb 2005, 11:36
Zitat von jbg:
Genau. Und was passiert wenn man dein Objekt in eine TObject Referenz steckt? Dann wird bei obj.Free das TObject.Free aufgerufen und nicht deine neue Version.
Probleme sehe ich dann nur wenn Delphi das an irgendeiner Stelle selbtständig macht. (Ich weiß nicht wann sowas passiert, gib mir doch mal bitte ein Beispiel [Meine Klasse ist von TList abgeleitet]).
Geht man davon aus, daß jemand das von Hand macht dann sollte man ja OOP vollständig vermeiden. Derjenige der sowas manuell macht sollte sich auch schlau machen welche Auswirkungen das hat, oder?
Wie würdest du denn das lösen?
  Mit Zitat antworten Zitat
Benutzerbild von maximov
maximov

Registriert seit: 2. Okt 2003
Ort: Hamburg
548 Beiträge
 
Delphi 2005 Professional
 
#27

Re: Methode "Free" selbst implementieren (Assemble

  Alt 23. Feb 2005, 11:51
Wenn dies alles dafür gedacht ist, objekte am leben zu erhalten, die noch referenziert werden, warum verwendest du dann nicht die automatisch COM-refCount geschichte? Du müsstest dann nur leider mit interface-refenren arbeiten.
mâxîmôv.

{KDT}
  Mit Zitat antworten Zitat
VizeTE

Registriert seit: 31. Dez 2002
178 Beiträge
 
Delphi 5 Enterprise
 
#28

Re: Methode "Free" selbst implementieren (Assemble

  Alt 23. Feb 2005, 12:06
Zitat von maximov:
Wenn dies alles dafür gedacht ist, objekte am leben zu erhalten, die noch referenziert werden, warum verwendest du dann nicht die automatisch COM-refCount geschichte? Du müsstest dann nur leider mit interface-refenren arbeiten.
Nee, dafür war es nicht gedacht. Eigentlich wollte ich für Free einen Parameter übergeben mit dem entschieden wird ob Kind-Elemente ebenfalls freigegeben werden sollen. Ich wollte das nicht als Eigenschaft implementieren weil das für mich einfach eindeutiger erschien wenn es exakt ein Free gibt welches einen Parameter verlangt.
  Mit Zitat antworten Zitat
Benutzerbild von maximov
maximov

Registriert seit: 2. Okt 2003
Ort: Hamburg
548 Beiträge
 
Delphi 2005 Professional
 
#29

Re: Methode "Free" selbst implementieren (Assemble

  Alt 23. Feb 2005, 15:24
Zitat von VizeTE:
Zitat von maximov:
Wenn dies alles dafür gedacht ist, objekte am leben zu erhalten, die noch referenziert werden, warum verwendest du dann nicht die automatisch COM-refCount geschichte? Du müsstest dann nur leider mit interface-refenren arbeiten.
Nee, dafür war es nicht gedacht. Eigentlich wollte ich für Free einen Parameter übergeben mit dem entschieden wird ob Kind-Elemente ebenfalls freigegeben werden sollen. Ich wollte das nicht als Eigenschaft implementieren weil das für mich einfach eindeutiger erschien wenn es exakt ein Free gibt welches einen Parameter verlangt.
IMO macht es mehr sinn, das innerhalb der objekt-beziehungen die besitzansprüche genau geklärt sind und somit nur objekte freigegeben werden, die einem auch tatsächlich gehören. Diese lösung mit dem parameter erscheint mir mehr als unglücklich. Mir ist kein fall bekannt, bei dem ein delphi-priogrammierer gezwungen war einen ähnlichen weg zu gehen. IMO sind Free und Destroy unantastbar.
mâxîmôv.

{KDT}
  Mit Zitat antworten Zitat
VizeTE

Registriert seit: 31. Dez 2002
178 Beiträge
 
Delphi 5 Enterprise
 
#30

Re: Methode "Free" selbst implementieren (Assemble

  Alt 24. Feb 2005, 08:15
Zitat von maximov:
IMO macht es mehr sinn, das innerhalb der objekt-beziehungen die besitzansprüche genau geklärt sind und somit nur objekte freigegeben werden, die einem auch tatsächlich gehören. Diese lösung mit dem parameter erscheint mir mehr als unglücklich. Mir ist kein fall bekannt, bei dem ein delphi-priogrammierer gezwungen war einen ähnlichen weg zu gehen. IMO sind Free und Destroy unantastbar.
Jaja, da habe ich mich ja schon überzeugen lassen. Nun bin ich am überlegen ob ich das halt doch vorher per Property mache (wie in TObjectList), versuche das mit dem RefCount umzusetzen oder vielleicht laß ich das Objekt wissen wem es gehört. Dann könnten die Listen nur die Eigenen freigeben. Das ist vielleicht die flexibelste Möglichkeit.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 5     123 45      


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