Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Formular in DLL (https://www.delphipraxis.net/146991-formular-dll.html)

sebi87 30. Jan 2010 20:11


Formular in DLL
 
Hallo Leute,

ich habe eines meiner Formulare in eine DLL ausgelagert und erzeuge und öffne das Formular von meiner HAuptanwendung aus.

Funktion in der DLL um das Formular ertellen und anzuzeigen
Delphi-Quellcode:
procedure PluginForm(appHandle: THandle) ;
var
  oldApp : THandle ;
begin
  oldApp := Application.Handle ;
  if appHandle = 0 then appHandle := GetActiveWindow ;
  Application.Handle := appHandle ;
  try
    with TForm1.Create(Application) do
    try
      ShowModal ;
    finally
      Release ;
    end ;
 except
   On E: Exception Do Application.HandleException(E) ;
  end ;
  Application.Handle := oldApp ;
end ;
in meinem Hauptprogramm rufe ich das ganze dann so auf:
Delphi-Quellcode:
PluginForm(Application.Handle) ;
Natürlich nachdem die DLL ordnungsgemäß geladen wurde.

Jetzt habe ich nur das Problem das nach dem Schließen des Formulars dieser Fehler auftaucht
Zitat:

Im Projekt ... ist eine Exeption der Klasse EAccessViolation aufgetreten. Meldung: 'Zugriffsverletzung bei
Adresse 01391861. Lesen von Adresse 903E8739'. Prozeß wurde angehalten. Mit Einzelne Anweisunf oder Start fortsetzen
Danach läuft das ganze wieder ohne Probleme.

Wie kann ich diesen Fehler beheben.
Bitte um Hilfe, ich bin am verzeifeln.

Grüße Sebastian

mkinzler 30. Jan 2010 20:21

Re: Formular in DLL
 
Ich würde das Fenster nicht der Application zuordnen (Owner). Am Besten Nil und dann beim Beenden der Dll freigeben

sebi87 30. Jan 2010 20:56

Re: Formular in DLL
 
Mit
Delphi-Quellcode:
nil
tritt der selbe Fehler auf...

Die DLL wird beim Beenden des Programms wieder Freigegeben.

Der Fehler tritt bei Schliesen des Fensters auf.

Grüße Sebastain

mkinzler 30. Jan 2010 21:01

Re: Formular in DLL
 
Du musst die form innerhalb der Dll freigeben

sebi87 31. Jan 2010 08:16

Re: Formular in DLL
 
Und wie gebe ich die Form in der DLL Frei?

Hat da jemand ein kleines Beispiel?

Grüße Sebastian

SirThornberry 31. Jan 2010 08:26

Re: Formular in DLL
 
so wie du die Funktion PluginForm hast brauchst du einfach nur noch eine weitere Funktion machen die du im OnDestroy deiner Anwendung aufrufst welche dann die Form in der DLL frei gibt.

Pseudocode
Delphi-Quellcode:
procedure PluginForm();
begin
  GlobalForm := TGlobalForm.Create();
end;

procedure PlugoutForm();
begin
  GlobalForm.Release();
end;

sebi87 31. Jan 2010 09:25

Re: Formular in DLL
 
Das ist ja auch kein Problem,

die Speicherzugriffverletzung entsteht nach dem Rechtmäßigen schließen des Formulars. Die Anwendung selber läuft weiter.

Nochmals zum Ablauf.

1. laden der DLL beim Anwendungsstart
2. Öffnen des Formulars aus der DLL duch Button
3. Arbeiten mit dem Formular
4. Schließen des Formulars
5. Anwendung läuft weiter
6. Entfernen der DLL beim Anwendungs Ende

Der Fehler erscheint zwischen 4. und 5.


Grüße Sebastian

himitsu 31. Jan 2010 09:38

Re: Formular in DLL
 
Es ist halt nicht so einfach, bzw. unmöglich, wenn versucht die VCL einer DLL mit der einer EXE oder anderen DLL zu verbinden.

Binde also deine Forms der DLL nicht an die Applikation der EXE.

sebi87 31. Jan 2010 10:32

Re: Formular in DLL
 
Wie muss ich das verstehen?

Es muss doch möglich sein ein Formular aus einer DLL zu Laden

mkinzler 31. Jan 2010 10:37

Re: Formular in DLL
 
Ja aber wie schon öfters gesagt, muss die komplette Verwaltung und alle Zugriffe adaruf innerhalb der Dll erfolgen.

himitsu 31. Jan 2010 10:40

Re: Formular in DLL
 
Eine Delphi-DLL hat erstmal grundsätzlich eine eigene VCL, RTTI und ein eigenes Speichermanagement.

Die RTTI der DLL ist nicht kompatibel zu der der EXE
und auch die Speichermanager arbeiten nicht zusammen.

Drum ist es erstmal grundsätzlich auch nicht möglich Strings, DynArrays und Objekte über die Modulgrenzen (EXE/DLL) hinweg zu benutzen.

[add]
Was den Speichermanager betrifft, da gibt es das Thema "SharedMemoryManager", welches da etwas ermöglicht, aber für die RTTI gibt es sowas nicht.

Einzige Möglichkeit sowas für die RTTI hinzubekommen sind Packages (Laufzeit-Packages / Runtimepackages).

sebi87 31. Jan 2010 10:42

Re: Formular in DLL
 
Kann mir vielleicht jemand ein Beispiel Code schicken wie ich das dann machen muss?

Wäre echt super

himitsu 31. Jan 2010 10:47

Re: Formular in DLL
 
PS: Hab oben noch was dazueditiert.


Delphi-Quellcode:
PluginForm(Application.Handle) ;
Wie?
z.B. indemdu alle Zugriffe auf die Form in der DLL auch nur innerhalb der DLL machts.

Dazu zählt auch, daß du nichts von der EXE in die DLL durchschleifst.


Nichtmal Strings dürfen einfach so übergeben werden.


Ausnahmen: siehe oben

mkinzler 31. Jan 2010 10:51

Re: Formular in DLL
 
Füge ienfach für alle Operationen Funktionen im Interface der DLL an:


Delphi-Quellcode:
function CreateForm: Boolean;
begin
    Form := TDieForm.Create(Nil);
    ...
end;

procedure OpenForm;
begin
   Form.Show;
end;

procedure HideForm;
...

sebi87 31. Jan 2010 11:01

Re: Formular in DLL
 
Also wenn ich das richtig vertanden habe dann liegt der Fehler in dem Aufrauf meines Formulars
Delphi-Quellcode:
PluginForm(appHandle: THandle)
Ich muss damit es geht alle Funktionen die ich zum anzeigen Benötige also Create, Show, Destroy in der DLL erstellen und Exportieren. So greift dann das HAuptprogramm nur auf die Funktionen zu und nicht auf die DLL, richtig?


Grüße Sebastian

mkinzler 31. Jan 2010 11:04

Re: Formular in DLL
 
Auf die Dll schon, aber nicht auf die (VCL-)Objekte darin

sebi87 31. Jan 2010 11:16

Re: Formular in DLL
 
Ich kapier es irgendwie nicht...

Habe den Code jetzt geändert

DLL:
Delphi-Quellcode:
procedure PluginForm ;
var
  PluginForm : TForm ;
begin
  PluginForm := TForm1.Create(nil) ;
  try
    PluginForm.ShowModal ;
  finally
    PluginForm.Release ;
    PluginForm := nil ;
  end ;
end ;
und den Aufruf:
Delphi-Quellcode:
  AHandle := LoadLibrary(PChar(ExtractFilePath(Application.ExeName)+'\Plugins\Project2.dll'));
  if AHandle <> 0 then begin
    @PluginForm := GetProcAddress(AHandle, 'PluginForm');
    if @PluginForm <> nil then
    begin
      PluginForm ;
    end;
    FreeLibrary(AHandle);
  end;
Aber es funktionier immer noch nicht

SirThornberry 31. Jan 2010 12:17

Re: Formular in DLL
 
Kannst du mal zeigen wie PluginForm innerhalb deiner Exe definiert ist?
Irgendwas verschweigst du uns denn bei mir funktioniert das ohne Probleme.

sebi87 31. Jan 2010 17:40

Re: Formular in DLL
 
Hmm also das PluginForm in der EXE ist so definiert:

Delphi-Quellcode:
  TPluginForm = procedure ;

var
  AHandle : THandle ;
  PluginForm : TPluginForm ;

sebi87 2. Feb 2010 09:12

Re: Formular in DLL
 
Kann mir vielleicht ein Beispiel schicken wie es Funktioniert?

Wäre echt super.

Danke

Grüße Sebastian


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:16 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