Delphi-PRAXiS
Seite 5 von 7   « Erste     345 67      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi "Unsterbliche" Klassen (https://www.delphipraxis.net/58928-unsterbliche-klassen.html)

Neutral General 15. Dez 2005 14:43

Re: "Unsterbliche" Klassen
 
Delphi-Quellcode:
unit Unverwundbar;

interface

uses Classes, Sysutils;

procedure FreeAndNil(var Obj);
// Für das FreeAndNil darf in der Unit wo das Projekt eingebunden ist
// kein Sysutils eingebunden sein damit mein FreeAndNil benutzt wird :mrgreen:

type
 TUnverwundbar = class;
 
 TUnvThread = class(TThread)
 private
  procedure MakeUnv;
 public
  Parent: TUnverwundbar;
 protected
  procedure Execute; override;
 end;

TUnverwundbar = class(TObject)
 private
  Seele: TUnvThread;
 public
  TestString: String;
  constructor Create;
  destructor Destroy; override;
  procedure FreeInstance; override;
 end;

implementation

uses UnvDemo;

{ TUnverwundbar }

constructor TUnverwundbar.Create;
begin
 inherited Create;
 Seele := TUnvThread.Create(true);
 Seele.Parent := Self;
 Seele.Resume;
end;

destructor TUnverwundbar.Destroy;
begin

end;

procedure TUnverwundbar.FreeInstance;
begin

end;

procedure FreeAndNil(var Obj);
begin

end;

{ TUnvThread }

procedure TUnvThread.Execute;
begin
  while not Terminated do
  begin
   Synchronize(MakeUnv);
  end;
end;

procedure TUnvThread.MakeUnv;
begin
 if Self.Parent = nil then begin
  Self.Parent := TUnverwundBar.Create; // Das klappt kein bisschen xD
 end;  // außerdem wäre das auch nur demo weil der string und die Propertys ja die alten sein müssten^^
end;
end.
Also bis jetzt ist meine Klasse fast un-unverwundbar... :(
Also wer mir helfen kann/will der kann das gerne tun ^^
Auch wenn jetzt meine geniale FreeAndNil-Abwehr geplatzt ist :mrgreen:
Obwohl ich die ja nicht mehr nötig hätte wenn ich Klasse := nil umgehen könnte....

Dax 15. Dez 2005 14:43

Re: "Unsterbliche" Klassen
 
Zitat:

Zitat von MaBuSE
Dann kann ich selbst ausprobieren, ob TObject(Klasse).Free; funktioniert.

Ich füchte das wird nix ;) Free ruft Destroy auf, Destroy ruft FreeInstance auf, und FreeInstance ist nun mal virtuell und damit nur über patchen wieder auf TObject zurückbiegbar.

Edit: So, killen wir die Klasse mal.
Delphi-Quellcode:
FreeMem(Pointer(Unverwundbar), Unverwundbar.InstanceSize);

ichbins 15. Dez 2005 14:47

Re: "Unsterbliche" Klassen
 
Zitat:

Zitat von Neutral General
Delphi-Quellcode:
// Für das FreeAndNil darf in der Unit wo das Projekt eingebunden ist
// kein Sysutils eingebunden sein damit mein FreeAndNil benutzt wird :mrgreen:

das is ja aber auch ein Witz...

Neutral General 15. Dez 2005 14:47

Re: "Unsterbliche" Klassen
 
Zitat:

Zitat von Dax
Zitat:

Zitat von MaBuSE
Dann kann ich selbst ausprobieren, ob TObject(Klasse).Free; funktioniert.

Ich füchte das wird nix ;) Free ruft Destroy auf, Destroy ruft FreeInstance auf, und FreeInstance ist nun mal virtuell und damit nur über patchen wieder auf TObject zurückbiegbar.

Edit: So, killen wir die Klasse mal.
Delphi-Quellcode:
FreeMem(Pointer(Unverwundbar), Unverwundbar.InstanceSize);

Hehe


Delphi-Quellcode:
var Unv : TUnverwundbar
FreeMem(Pointer(Unv), TUnverwundbar.InstanceSize);
Das bringt nix :P

Dax 15. Dez 2005 14:54

Re: "Unsterbliche" Klassen
 
Hm, stimmt sogar.

Delphi-Quellcode:
var Unv : TUnverwundbar;
Unv.CleanupInstance;
FreeMem(Pointer(Unv), TUnverwundbar.InstanceSize);
Sollte aber eventuell gehen.. Oder?

Neutral General 15. Dez 2005 14:55

Re: "Unsterbliche" Klassen
 
eh jain... also beim ersten klick nicht aber beim zweiten gibts ne AV...

Aber wie ich festgestellt hab kommt die AV nicht wegen der Klasse.. Denn die funktioniert danach noch einwandfrei :mrgreen: :P
Cleanupinstance setzt die Klasse soweit ich weiß ja nur zurück.

MaBuSE 15. Dez 2005 16:10

Re: "Unsterbliche" Klassen
 
Zitat:

Zitat von Dax
Delphi-Quellcode:
var Unv : TUnverwundbar;
Unv.CleanupInstance;
FreeMem(Pointer(Unv), TUnverwundbar.InstanceSize);
Sollte aber eventuell gehen.. Oder?

Mach es doch so, das funktioniert auf jeden Fall. (getestet)

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var x : TUnverwundbar;
begin
  x := TUnverwundbar.Create;
  x.TestString := 'Test';

  x.CleanupInstance;      // Aufräumen
  SysFreeMem(Pointer(x)); // und aus Speicher entfernen

  Caption := x.TestString;
end;
Ein paar Worte dazu:
Wenn ein (obj as TObject).Free aufgerufen wird,
wird Destroy, _ClassDestroy, FreeInstance aufgerufen.
in FreeInstance wird dann CleanupInstance und
MemoryManager.FreeMem (der auf SysFreeMem zeigt) aufgerufen.

Obiges Beispiel macht also genau das selbe wie x.Free sollte :mrgreen:

Hier noch mal ein Auszug aus der System.pas zum Nachlesen und verstehen:
(Anmerkung: in der system.pas sind manche Proueduren und Funktionen mit dem beginnenden Unterstrich (z.B. _ClassDestroy). Diese Funktionen benutzen die "CompilerMagic". Das bedeutet, das teile der Funktionalität fest im Compiler eingebaut sind. Nach dem "Destroy" eines Objektes wird immer _ClassDestroy aufgerufen, obwohl das in der System.pas gar nicht programmiert ist. Das baut der Compiler von sich aus ein ;-) It's magic, compiler magic.)
Delphi-Quellcode:
{*******************************************************}
{       Borland Delphi Runtime Library                 }
{       System Unit                                    }
{       Copyright (C) 1988,99 Inprise Corporation      }
{*******************************************************}
unit System; { Predefined constants, types, procedures, }
...
interface
...
type
...
  TObject = class
    ...
    procedure Free;
    procedure CleanupInstance;
    ...
    procedure FreeInstance; virtual;
    destructor Destroy; virtual;
  end;
...
  PMemoryManager = ^TMemoryManager;
  TMemoryManager = record
    GetMem: function(Size: Integer): Pointer;
    FreeMem: function(P: Pointer): Integer;
    ReallocMem: function(P: Pointer; Size: Integer): Pointer;
  end;
...
{ Procedures and functions that need compiler magic }
procedure _ClassDestroy(Instance: TObject);
function _FreeMem(P: Pointer): Integer;
...
implementation
...
procedure TObject.Free;
begin
  if Self <> nil then
    Destroy; // Free ruft Destroy auf
end;
...
destructor TObject.Destroy;
begin
  // Destroy ist leer :shock:
  // Es wird aber dann automatisch _ClassDestroy(self) aufgerufen
end;
..
procedure _ClassDestroy(Instance: TObject);
begin
  Instance.FreeInstance; // aha, hier also ;-) !!!
end;
...
procedure TObject.FreeInstance;
begin
  CleanupInstance; // Räumt auf
  _FreeMem(Self);  // Entfernt Objekt aus dem Speicher
end;
...
procedure TObject.CleanupInstance;
var
  ClassPtr: TClass;
  InitTable: Pointer;
begin
  ClassPtr := ClassType;
  InitTable := PPointer(Integer(ClassPtr) + vmtInitTable)^;
  while (ClassPtr <> nil) and (InitTable <> nil) do
  begin
    _FinalizeRecord(Self, InitTable);
    ClassPtr := ClassPtr.ClassParent;
    if ClassPtr <> nil then
      InitTable := PPointer(Integer(ClassPtr) + vmtInitTable)^;
  end;
end;
...
function _FreeMem(P: Pointer): Integer;
begin
  if P <> nil then
  begin
    Result := MemoryManager.FreeMem(P); // Aha, also der Memorymanager !!!
    if Result <> 0 then
      Error(reInvalidPtr);
  end
  else
    Result := 0;
end;
...
var
  MemoryManager: TMemoryManager = (
    GetMem: SysGetMem;
    FreeMem: SysFreeMem; // Der MemoryManager benutzt per Default SysFreeMem
    ReallocMem: SysReallocMem);
...
function SysFreeMem(P: Pointer): Integer;
begin
  __free(P); // ist extern definiert
  Result := 0;
end;
...
end;

Neutral General 15. Dez 2005 16:14

Re: "Unsterbliche" Klassen
 
Mist -.-^^
Ich programmier ne eigene OOP Programmiersprache ("Michi" (an "Pascal" angelehnt^^)) und da gibts dann unverwundbare Klassen :mrgreen:

Neotracer64 15. Dez 2005 16:45

Re: "Unsterbliche" Klassen
 
Hook doch alle gefährlichen Funktionen. :-D

Neutral General 15. Dez 2005 17:21

Re: "Unsterbliche" Klassen
 
Hab ich ja versucht aber was willst du z.B gegen

Delphi-Quellcode:
Klasse := nil;
machen ?


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:03 Uhr.
Seite 5 von 7   « Erste     345 67      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz