Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Inztanz macht neue Instanz der gleichen Klasse (https://www.delphipraxis.net/12090-inztanz-macht-neue-instanz-der-gleichen-klasse.html)

Minz 20. Nov 2003 14:14


Inztanz macht neue Instanz der gleichen Klasse
 
Hallö,

also ich habe mal folgendes ausprobiert:

Delphi-Quellcode:
constructor TMyObject.create(hand: LongWord;c: integer);
begin
  inherited create(nil);
  FHandle:=hand;
  FCount:=c;
  execute;
end;

procedure TMyObject.Execute;
var mo:TMyObject;
begin
  if FCount<100 then mo:=TMyObject.create(FHandle, FCount+1);
  PostMessage(FHandle,WM_CreateDestroy,1,1);
  Self.free;
end;
Nun kann mir da jemand weiterhelfen? Er scheint bis 100 lauter Objekte zu erstellen, was er ja auch soll, nur dann steigt er mit einer Fehlermeldung aus mit Zugriffsverletzung 00000 bei 00000 oder so. Dies kommt ja eigentlich dann wenn versucht wird auf etwas zuzugreifen, was nicht da ist, aber um wen oder was handelt es sich dabei?

Aus dem Hauptfenster heraus wird das ganze in Gang gesetzt.

Gruß Minz

choose 20. Nov 2003 14:40

Re: Inztanz macht neue Instanz der gleichen Klasse
 
Hallo Minz,

im wesentlichen Handelt es sich bei Deinem Code um eine Rekursion, so dass die beiden Zeilen
Delphi-Quellcode:
PostMessage(FHandle,WM_CreateDestroy,1,1);
Self.free;
erst dann durchlaufen werden, wenn FCount>=100 ist.

Kann es sein, dass der Fehler in einer dieser beiden Zeilen auftritt?
Wer behandelt die die Nachricht WM_CreateDestroy und tritt der Fehler vielleicht dort auf (dann allerdings ansynchron nachdem die Objekte wieder freigegeben wurden)?
Was passiert, wenn Du bereits das erste Exemplar mit
Delphi-Quellcode:
TMyClass.Create(AHandle, 100);
erzeugst?

EDIT: Delphi-Tags

Minz 20. Nov 2003 15:33

Re: Inztanz macht neue Instanz der gleichen Klasse
 
hmm dann muss ich das ganze wohl doch mit Threads machen, damit PostMessage und Self.free durchlaufen werden.

Die Botschaft wird vom Hauptfenster verarbeitet. Wenn ich mit 100 starte gibts keine Probleme.

Habs auch schon mit Threads probiert, aber da meldet der mir wieder abstrakte Fehler, arghl

choose 20. Nov 2003 15:40

Re: Inztanz macht neue Instanz der gleichen Klasse
 
Du hast durch den Debugger der IDE die Möglichkeit, den genauen Ort des Fehlers zu lokalisieren.
Wenn ich Dein Problem richtig verstehe, sollte er entweder beim Freigeben (warum, wäre mir allerdings unverständlich) eines der Objekte (welches?) oder bei der Verarbeitung der Nachricht auftreten (wobei, wird vielleicht versucht, auf eines der Objekte zuzugreifen? Achtung: Asynchron!).

Wo genau tritt welcher Fehler (Exceptionklasse und -text) auf?

Minz 20. Nov 2003 15:54

Re: Inztanz macht neue Instanz der gleichen Klasse
 
Hallo,

Ich habs mal mit Threads ausprobiert und hat auch geklappt mit den Startwerten 100, 99, 98 aber nicht mit 0...da gabs dann erstmal einen üblen Systemhänger :(

Jetzt kann ich nicht mal mehr das Programm starten...da kommt dann eine Fehlermeldung Runtime-Error 216 at Adress ...

und das obwohl ich schon in der Projektdatei einen Breakpoint gesetzt habe.

Hier mal mein Code, ist ja nix wildes:

unit Main:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  myobject:=TMyObject.create(handle,0);
end;

procedure TForm1.GetMessage(var msg: TMessage);
begin
  i:=i+msg.wparam;
  label1.caption:=inttostr(i);
end;
unit MyObject:
Delphi-Quellcode:
constructor TMyObject.create(hand: LongWord;c: integer);
begin
  FHandle:=hand;
  FCount:=c;
  inherited create(false);
  FreeOnTerminate:=true;
end;

procedure TMyObject.Execute;
var mo:TMyObject;
begin
  if FCount<100 then begin
    mo:=TMyObject.create(FHandle, FCount+1);
  end;
  PostMessage(FHandle,WM_CreateDestroy,1,1);
end;
Gruß Minz

choose 20. Nov 2003 16:20

Re: Inztanz macht neue Instanz der gleichen Klasse
 
Entschuldige, dass ich es nicht vorher gesehen habe: Es sollte vermieden werden, Free oder Destroy innerhalb des Konstruktors (oder einer von ihm aufgerufenen Methode) zu verwenden. Wenn Du wirklich willst, das ein Objekt beim Erstellen freigegeben wird, wirf innerhalb des Konstruktors eine Exception, vor allem aber: Finde eine andere Lösung!

Ein Ansatz mit Threads hingegen könnte so aussehen:
Delphi-Quellcode:
type
  TMyObject = class(TThread)
  private
    FHandle: Cardinal;
    FCount: Integer;
  protected
    procedure Execute; override;
  public
    constructor Create(const AHandle: Cardinal; const ACount: Integer);
  end;

constructor TMyObject.Create(const AHandle: Cardinal;
  const ACount: Integer);
begin
  inherited Create(True);

  FHandle:= AHandle;
  FCount:= ACount;

  FreeOnTerminate:= True;
  Resume;
end;

procedure TMyObject.Execute;
begin
  if not Terminated then
  begin
    if FCount<100 then
      TMyObject.Create(FHandle, FCount+1);
    //cannot post message WM_CreateDestroy: Not defined
  end;
end;
Bitte überlege Dir genau, was Du machst. Vielleicht solltest Du in einem neue DP-Thread das Problem und eine mögliche Herangehensweise diskutieren?

Minz 20. Nov 2003 17:30

Re: Inztanz macht neue Instanz der gleichen Klasse
 
Achso, meinst du damit, dass wenn Execute aufgerufen wird,

er mit create eventuell noch nicht fertig ist, und dadurch dann
trouble entsteht?

Mit den Threads hab ich es fast genauso, nur das ich nicht Resume benutze,
sondern inherited create(false) verwende.

Hast du dir dabei was gedacht?

Danke jedenfalls für deine Unterstützung :hello:

Gruß Minz

choose 20. Nov 2003 17:46

Re: Inztanz macht neue Instanz der gleichen Klasse
 
Zitat:

Zitat von Minz
[...] meinst du damit, dass wenn Execute aufgerufen wird,
er mit create eventuell noch nicht fertig ist [...]?

Du hast [i]Execute sogar aus dem Konstruktor heraus aufgerufen, er kann somit nicht "fertig sein".

Zitat:

Zitat von Minz
Mit den Threads hab ich es fast genauso [...]. Hast du dir dabei was gedacht?

Ja. Lies am besten ein paar Tutorials über Threads, auch um zu verstehen, warum Execute im Delphi-Wrapper TThread nicht explizit aufgerufen werden muss und sie für Dein Problem (was willst Du denn eigentlich tun?!) wahrscheinlich keine geeignete Lösung bieten.

Minz 20. Nov 2003 17:48

Re: Inztanz macht neue Instanz der gleichen Klasse
 
Hi Choose,

hmm was so ein paar kleine Veränderungen alles bewirken können.
Habs jetzt nochmal zu Hause mit deiner Variante ausprobiert und läuft einwandfrei.
Aber ich bin bei inherited.create(false) geblieben :mrgreen:
Ein Unterschied nun ist die Zeile:

if not Terminated then

obwohl er in keinen Fall Terminated=false hat, denn er zählt genau bis 100 hoch.

:gruebel: :wall: :gruebel:

verstehe also nicht ganz, wieso das vorher nicht gefunzt hat. Lag bestimmt am Rechner :mrgreen:

Minz 20. Nov 2003 17:55

Re: Inztanz macht neue Instanz der gleichen Klasse
 
Zitat:

was willst Du denn eigentlich tun?!
Ich teste Möglichkeiten aus, um später Evolution zu simulieren.

Ich überlege derzeit, wie ich die Aufgaben verteile, was bearbeitet die Umwelt, was verarbeitet eine Zelle etc.

Die Vorstellung dabei mit unabhängigen Threads zu arbeiten und einen Windows-Nachrichtkrieg zu starten gefällt mir dabei sehr gut :lol:

Achso habe ganz vergessen zu erwähnen, dass ich später dann die Weltherrschaft an mich reißen will, aber bis dahin :angle:


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:12 Uhr.
Seite 1 von 2  1 2      

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