Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Dll und Variablen-Scope (https://www.delphipraxis.net/104208-dll-und-variablen-scope.html)

Sämy 29. Nov 2007 09:49


Dll und Variablen-Scope
 
Hallo

Ich habe eine Klasse, die ich als Singleton(nur eine Instanz) definiere:
Delphi-Quellcode:
type
  TPluginManager = class
  public
    class function getInstance: TPluginManager;
  end;

var
  instance: TPluginManager;

implementation

class function TPluginManager.getInstance: TPluginManager;
begin
  if not Assigned(instance) then
    instance := TPluginManager.Create;
  Result := instance;
end;
Wenn ich nun also TPluginManager.getInstance aufrufe, so bekomme ich dessen Instanz zurück.
Ich arbeite jedoch mit Dll's und wenn ich von dort aus TPluginManager.getInstance aufrufe, erhalte ich nicht mehr die in der Applikation erzeugte Instanz, sondern eine neue wird erstellt.
Wie kann ich dieses Problem umgehen?

Besten Dank!

RavenIV 29. Nov 2007 10:01

Re: Dll und Variablen-Scope
 
Zitat:

Zitat von Sämy
Ich habe eine Klasse, die ich als Singleton(nur eine Instanz) definiere:

Wo deklarierst Du die Klasse als singleton?
Kann das Delphi überhaupt?

In der DLL hast Du vermutlich einen anderen Scope, da ist die erste Instanz nicht bekannt.
Vermutlich müsstest Du sie an die DLL übergeben.

Korrgiert mich bitte, wenn ich Müll geschrieben habe.

sirius 29. Nov 2007 10:04

Re: Dll und Variablen-Scope
 
Du hast also in deinem Programm und in der DLL eine globale Variable Instance? Und demnach hast du dann zweimal ein Objekt deiner Klasse.
Sehe ich das so richtig?

Sämy 29. Nov 2007 10:19

Re: Dll und Variablen-Scope
 
Zitat:

Wo deklarierst Du die Klasse als singleton?
Kann das Delphi überhaupt?
Ich "deklariere" die Klasse als Singleton. Ich definiere einfach die getInstance-Funktion ein um die Singleton-Implementation zu erreichen.


Ich habe diese Klasse in einer eigenen Unit und diese binde ich in der Applikation, wie auch in der Dll ein.
Anschliessend erhalte in der Applikation, wie auch in der Dll (respk. jeder Dll, bei mehreren), eine eigene Instanz, obwohl ich gerne nur eine hätte.

Eine Übergabe der Variable kann ich leider nicht realisieren, da ich viele solche Singleton-Klassen habe und ich nicht weiss, welche alle in der Dll gebraucht werden. Respk. ich will nicht, wenn ich eine neue Singleton-Klasse erstelle, die Dll-Funktion ändern müssen...

sirius 29. Nov 2007 10:24

Re: Dll und Variablen-Scope
 
Durch die Unit, welche nur identisch in DLL und EXE, erreichst du ja nur, dass der Code identisch in beiden Programmen ist. Dadurch existiert die goabel Variable eben auch zweimal.
Das Problem könnte man über eine MMF lösen. Allerdings besteht dann ein weiteres Problem darin, das du ohne Sharemem nicht kreuz und quer Klassen zwischen DLL und EXE austauschen kannst.

Sämy 29. Nov 2007 10:35

Re: Dll und Variablen-Scope
 
Zitat:

Zitat von sirius
Durch die Unit, welche nur identisch in DLL und EXE, erreichst du ja nur, dass der Code identisch in beiden Programmen ist. Dadurch existiert die goabel Variable eben auch zweimal.

Dies ist mir schon klar.


Da ich ShareMem sowieso schon verwende, wäre der zweite Ansatz interessant. Wie könnte ich dies realisieren?

sirius 29. Nov 2007 11:15

Re: Dll und Variablen-Scope
 
Vielleicht so:
Delphi-Quellcode:
type
  PPlugInManager = ^TPluginManager;
  TPluginManager = class
  public
    class function getInstance: TPluginManager;
  end;


const InstanceName='HalloIchMUSSAufDemRechnerGanzEinamligSein';
var InstanceMMF:THandle=0;

implementation

uses windows, sysutils;

class function TPluginManager.getInstance: TPluginManager;
var Instance:PPluginManager;
    InstanceExists:boolean;
    vInstanceName:string;
begin
  if InstanceMMF=0 then
  begin
    vInstanceName:=InstanceName+inttohex(getcurrentprocessid,8);
    InstanceMMF:=createfilemapping(cardinal(-1),nil,PAge_ReadWrite,0,4,Pchar(vInstanceName));
    InstanceExists:=getlasterror=ERROR_ALREADY_EXISTS;
  end
  else
    InstanceExists:=true;
  Instance:=mapviewoffile(InstanceMMF,FILE_MAP_ALL_ACCESS,0,0,0);
  try
    if InstanceExists then
      result:=Instance^
    else
    begin
      result:=TPluginManager.Create;
      Instance^:=result;
    end;
  finally
    unmapviewoffile(Instance);
  end;
end;

//irgendwann sollte auch mal closehandle(InstanceMMF) aufgerufen werden. Und das in jeder DLL und Exe.
// vielleicht in einer speziellen Free-Methode (du musst ja auch irgendwann Free bzw. Destroy aufrufen)

Sämy 29. Nov 2007 11:27

Re: Dll und Variablen-Scope
 
Besten Dank für die Unterstützung!

Es funktioniert.
Gruss Sämy


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:51 Uhr.

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