Delphi-PRAXiS
Seite 2 von 4     12 34      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Object (Interface) <> nil (https://www.delphipraxis.net/193802-object-interface-nil.html)

EWeiss 11. Sep 2017 14:24

AW: Object (Interface) <> nil
 
Zitat:

Zitat von sakura (Beitrag 1380795)
Zitat:

Zitat von EWeiss (Beitrag 1380794)
Denn die Anwendung weis nicht ob das Object in der DLL frei ist oder nicht.

Wie sollte es die Anwendung den wissen, wenn diese nicht informiert wird? :gruebel:

...:cat:...

Macht das ein normales Menu auch?
Ich möchte unnötige Funktionen vermeiden wenn das möglich ist.

Hmm...

Vielleicht bin ich auch im Moment etwas überfordert.
Ärgere mich schon lange damit rum.

Zitat:

•Niemals eine Referenz auf das Objekt behalten und nutzen! Immer nur mit dem Interface arbeiten. Schon gar nicht das Objekt mit Free freigeben und damit allen Interfaces unter dem Allerwertesten wegziehen. Das gibt sehr schöne Fehler...
Habe es behoben vorher habe ich in Destroy Free verwendet jetzt beende ich meine Windows ohne Free.
und das Object ist trotzdem NIL.

OK muss mal sehen wie ich das hinbiege.

gruss

stahli 11. Sep 2017 14:54

AW: Object (Interface) <> nil
 
Ich habe jetzt Dein Problem und den Hintergrund der Frage nicht eindeutig verstanden.

Wenn Du von TInterfacedPersistent ableitest, gibt es jedenfalls keine Referenzählung und keine automatische Freigabe des Objektes.

Wenn Du eine Referenzzählung benutzt, also z.B.

Var1 := O;
Var2 := O;
Var3 := O;

dann wird das Objekt O freigegeben, wenn allen 3 Variablen Nil (oder ein anderes Objekt) zugewiesen wurde und keine weitere Referenz auf O existiert.

Wenn Du statt dessen O.Free aufrufst, hast Du hängende Pointer auf ein freigegebenes Objekt. Das sollte man natürlich vermeiden.


Offenbar brauchst Du die Verwendung als Interface in einer DLL.
Dann kannst Du entweder automatische Referenzzählung und -Freigabe verwenden und solltest aber sämtliche Zugriffe auf das Objekt auch über ein Interface regeln oder Du verzichtest auf die Referenzzählung und regelst die Lebenszeit des Objektes und die Zuweisung aller entsprechenden Variablen selbst.

Ggf. könnte man globale Methoden einrichten, die das abwickeln.
procedure CreateMyObject;
procedure DestroyMyObject;
Je nach Zielstellung und Umständen gibt es da sicher verschiedene Möglichkeiten.

Neutral General 11. Sep 2017 15:02

AW: Object (Interface) <> nil
 
Ich muss gestehen dass ich den Thread nur überflogen habe aber kann es sein dass die Lösung des Problems wäre dass dein Programm und die DLL einfach die einfach Regel befolgen: "Wer es erstellt, der gibt es auch frei"?

Wenn die DLL ein PopupMenu(Item) erstellt, dann geht die Anwendung davon aus dass dieses Item existiert und zwar solange bis die DLL der Anwendung mitteilt, dass das Item freigegeben werden soll. Die Anwendung muss der DLL vertrauen und umgekehrt und niemand darf dem anderen reinpfuschen. Das ist schon die halbe Miete.

EWeiss 11. Sep 2017 15:06

AW: Object (Interface) <> nil
 
Ich erstelle ein Menu basierend auf Interface.

In der Anwendung..

Delphi-Quellcode:
  PopUpMenu := CTRL_PopUpMenuCreate;


Delphi-Quellcode:
function CTRL_PopUpMenuCreate(): ISkinPopUpMenu; stdcall; external dllfile;

usw..

Ich möchte nichts anderes als meiner Anwendung mitteilen das dass erstellte Object Nil ist.
Und nicht Quasi aus einer Laune heraus das erstelle Interface in der Anwendung selbst auf Nil setzen.
Zitat:

"Wer es erstellt, der gibt es auch frei"?
richtig nur ein Standard Menu macht das nicht oder?
Es liefert keine Funktion zurück welche da sagt hallo bin fertig du kannst mich platt machen. ;)


gruss

Neutral General 11. Sep 2017 15:13

AW: Object (Interface) <> nil
 
Warum ist das Objekt denn nil?
Wenn es erst gar nicht erstellt werden konnte kannst du ja mit CTRL_PopUpMenuCreate einfach "nil" zurückgeben.
Falls das Erstellen aber geklappt hat, dann gibt es keinen Grund warum du als DLL der Anwendung mitteilen müsstest dass das PopupMenu nil ist.
Denn entweder hat die Anwendung das selbst angeordnet oder die DLL hat sich eingemischt und das Popup der Anwendung freigegeben was genau dem widerspricht was ich oben gesagt hab.

Die Anwendung hat CTRL_PopUpMenuCreate aufgerufen also bleibt das erstelle PopupMenu solange erhalten bis die Anwendung es zerstört.

Alternativ kannst du vllt bei CTRL_PopUpMenuCreate als Parameter ein Callback übergeben lassen was die Anwendung informiert wenn das erstellte PopupMenu zerstört wurde.
Das wäre noch eine akzeptable Alternative denk ich.

EWeiss 11. Sep 2017 15:31

AW: Object (Interface) <> nil
 
Zitat:

Warum ist das Objekt denn nil?
Hat niemand etwas von gesagt das es Nil ist ;)

Delphi-Quellcode:
function CTRL_PopUpMenuCreate(): ISkinPopUpMenu; stdcall;
begin

  result := TSkinPopUpMenu.Create();
end;
das schlägt niemals fehl.
Mit CTRL_PopUpMenuCreate wird nur das Interface erstellt.

Was fehl schlagen könnte ist wenn das Window nicht erstellt wird.
Nach dem alle benötigten Funktionen gefüllt wurden wird das Window erstellt.
Delphi-Quellcode:
  gPMenu.hPopUpHandle := PopUpMenu.CreatePopupMenu(WinHandle);
  if gPMenu.hPopUpHandle <> 0 then
  begin
und liefert ein HWND zurück.

Das ist aber nicht mein Problem sondern ich sage es nochmal PopUpMenu auf Nil zu setzen wenn in der DLL TSkinPopUpMenu ebenfalls Nil ist.
Und das ganze wenn möglich ohne zusätzliche Funktionen da ich versuche das verhalten des originalen Menus zu emulieren.

Scheint so das mich keiner versteht. :)

gruss

TiGü 11. Sep 2017 15:38

AW: Object (Interface) <> nil
 
Zitat:

Zitat von EWeiss (Beitrag 1380808)
Das ist aber nicht mein Problem sondern ich sage es nochmal PopUpMenu auf Nil zu setzen wenn in der DLL TSkinPopUpMenu ebenfalls Nil ist.
Und das ganze wenn möglich ohne zusätzliche Funktionen da ich versuche das verhalten des originalen Menus zu emulieren.

Scheint so das mich keiner versteht. :)

Du bist eben auch kein Erklärbär.

Speicherst du dir irgendwo (in einer globalen Variablen) das Objekt mit dem Typ TSkinPopUpMenu in der DLL ab?
Und auf dieses rufst du dann TSkinPopUpMenu.Free auf?

EWeiss 11. Sep 2017 15:46

AW: Object (Interface) <> nil
 
Zitat:

Und auf dieses rufst du dann TSkinPopUpMenu.Free auf?
Nein ich rufe überhaupt kein Free auf. (Habe es geändert da man das nicht tun soll)

Das Interface ist dann frei wenn alle Referenzen auf 0 sind.
Also ich beende alle Ressourcen und zerstöre alle Objecte (Windows usw..) die vom Interface verwendet werden.
Danach ist dieses automatisch frei..

gruss

TiGü 11. Sep 2017 15:50

AW: Object (Interface) <> nil
 
Zitat:

Zitat von EWeiss (Beitrag 1380811)
Zitat:

Und auf dieses rufst du dann TSkinPopUpMenu.Free auf?
Nein ich rufe überhaupt kein Free auf. (Habe es geändert da man das nicht tun soll)

Das Interface ist dann frei wenn alle Referenzen auf 0 sind.
Also ich beende alle Ressourcen und zerstöre alle Objecte (Windows usw..) die vom Interface verwendet werden.
Danach ist dieses automatisch frei..

Dein Problem ist also damit gelöst?

Neutral General 11. Sep 2017 15:55

AW: Object (Interface) <> nil
 
Zitat:

Zitat von EWeiss (Beitrag 1380811)
Das Interface ist dann frei wenn alle Referenzen auf 0 sind.
Also ich beende alle Ressourcen und zerstöre alle Objecte (Windows usw..) die vom Interface verwendet werden.
Danach ist dieses automatisch frei..

Ist das nicht trotzdem genau das Problem von dem ich die ganze Zeit rede?
Die DLL macht das von der Anwendung angeforderte Objekt selbstständig und ohne dass die Anwendung es angefordert hat komplett unbrauchbar bzw. gibt alles frei.
Genau das soll die DLL nicht machen. Entweder du gibst das Objekt/die vom Objekt benutzen Resource erst frei wenn die Anwendung das von sich aus anfordert oder du teilst der Anwendung per Callback (wie weiter oben von mir vorgeschlagen) mit dass das Popupmenu was es eben erstellt hat jetzt kaputt ist.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:28 Uhr.
Seite 2 von 4     12 34      

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