DLL erstellen, mit Formular.

Rund um die LCL und andere Komponenten
Maik81ftl
Beiträge: 619
Registriert: Mi 9. Mär 2011, 16:34
OS, Lazarus, FPC: Ubuntu10.04 LTS (L 0.9.31.0 FPC 2.4.4)
CPU-Target: 64Bit
Wohnort: seit 01.06.2011 in Wahlstedt

Re: DLL erstellen, mit Formular.

Beitrag von Maik81ftl »

Glaub ich dir. war ja auch 'ne allgemeine Frage. :| Glaube dies schon mal via Unix hinbekommen zu haben. kann ich mich nun grad aber nicht errinnern. Aber weil du das gerate anschneidest.

Erhalte bei der verwendung von Interfaces und nachfolgenden Units die Meldung

Code: Alles auswählen

Test.lpr(1,1) Fatal: Can't find unit Interfaces used by Test
. glaube nicht, das dies normal ist.
Ubuntu 10.04 LTS ist meine Heimat. Lazarus ist meine Sprache :D und der Kreis Segeberg meine LIEBE :D

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: DLL erstellen, mit Formular.

Beitrag von m.fuchs »

MmVisual hat geschrieben:Ich habe hier einen Trick. Jetzt ist die Form echt Modal.
Der Haken: Wenn die EXE beendet wird, kommen gaaanz viele Adressen mit Zugriffsverletzung.


Ja, Modal funktioniert nicht. Das habe ich bei mir auch nur verwendet, damit auf das Beenden des Forms gewartet wird, bevor FreeAndNil zuschlägt. Inzwischen hab ich die DLL noch ein wenig erweitert:

Code: Alles auswählen

procedure ShowText(AText: String); stdcall;
begin
  if not Assigned(Form1) then begin
    try
      Form1 := TForm1.Create(Application);
      Form1.Memo1.Text := AText;
      Form1.ShowModal;
    finally
      FreeAndNil(Form1);
    end;
   end else begin
    Form1.Memo1.Text := AText;
    Form1.SetFocus;
  end;
end;
 
procedure HideForm; stdcall;
begin
  if Assigned(Form1) then
    Form1.Close;
end;
 
exports
  ShowText, HideForm;
 
begin
  Application.Initialize;
end.

Jetzt wird das Form nur dann neu erzeugt, wenn es nicht bereits angezeigt wird. Die HideForm - Prozedur rufe ich vom Hauptprogramm aus auf, wenn ich das Programm beenden möchte. Andernfalls wartet das Programm so lange, bis das DLL-Form von Nutzer per Hand geschlossen wird.

Nach den bisherigen Rückmeldungen aus der Mailingliste denke ich, dass dieser Weg der richtige ist. Mit den Einschränkungen (kein Modal u.ä.) kann ich soweit auch leben.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

khh
Beiträge: 489
Registriert: Sa 5. Apr 2008, 09:37
OS, Lazarus, FPC: Win Vista,Win 7 (L 0.9.29 FPC 2.4.1)
CPU-Target: 32Bit /64 Bit
Wohnort: Nähe Freiburg i.Br.

Re: DLL erstellen, mit Formular.

Beitrag von khh »

muss ich mir mal genauer ansehen.:-)
Wenn das mit einem Formular funktioniert, sollte es ja auch möglich sein andere Klassen in DLLs auszulagern, oder ?

Gruss KHH

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: DLL erstellen, mit Formular.

Beitrag von m.fuchs »

khh hat geschrieben:Wenn das mit einem Formular funktioniert, sollte es ja auch möglich sein andere Klassen in DLLs auszulagern, oder ?

Grundsätzlich ja, ABER: du kannst/solltest diese Klassen dann nur über einfach DLL-Methoden ansprechen. In meinem Fall wird das Ganze eine Reportingerweiterung für eine Software. Die Nutzdaten werden als Stringparameter (enthält dann eine Reihe von Objekten als JSON serialisiert) an eine Prozedur GenerateReport übergeben. Die erstellt dann das Form, die Reportkomponenten, deserialisiert die Daten, erzeugt aus den Objekten den Report und zeigt das Ganze an.
Es werden also eine ganze Reihe von Klassen sein, die aber alle nur innerhalb dieser einen Prozedur erzeugt (und wieder vernichtet) werden. Einziger Berührungspunkt zwischen Anwendung und DLL ist diese eine Prozedur.

Das tatsächliche Einbinden von Objekten aus DLLs (also beispielsweise ein Frame aus einer DLL laden) funktioniert wohl (noch) nicht.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

MmVisual
Beiträge: 1445
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: DLL erstellen, mit Formular.

Beitrag von MmVisual »

Ich habe noch ein Problem mit meiner Formular-DLL:

Immer wenn ich mit
CloseHandle(DLLHandle);
Die DLL entlade kommt eine Exception im Debugger:
Bild1.png
Bild1.png (6.08 KiB) 1444 mal betrachtet

Bild2.png


In der DLL gibt es kein Finalization Block, in dem irgend was noch gemacht wird.
Die DLL wird von der EXE nur geladen und bei beenden entladen, das Formular der DLL wird nicht gestartet.

Weiß jemand was da noch fehlt?

Grüße Markus


Edit:
Hier der Code von meiner EXE:

Code: Alles auswählen

Initialization
Begin
  DLLHandle := 0;
  slDllFunctions := TStringList.Create;
End;
 
Finalization
Begin
  //UnLoadDLL();   // <<< Die Zeile mit CloseHandle(DLLHandle); drin
  slDllFunctions.Free;
End;

Geladen wird die DLL sobald eine der DLL Funktionen zum erstan mal genutzt wird, daher nicht in Initialization.
Wenn ich das UnLoadDLL() im Finalization Block auskommentiere, dann kommt keine Exception mehr.
Als ob man nicht selbst bestimmen darf wann eine DLL entladen wird, sondern das muss das Lazarus alleine machen. :?:
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: DLL erstellen, mit Formular.

Beitrag von m.fuchs »

Hm, ehrlich gesagt kenne ich dieses CloseHandle nicht. Dynamisches Laden und Entladen habe ich auch mal gebaut, aber mit der Unit dynlibs. Sieht dann in meinem Falle so aus:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
type
  TMyProc = procedure (AText: String);stdcall;
var
  DllHandle: TLibHandle;
  MyProc: TMyProc;
begin
  try
    DllHandle := LoadLibrary('server.dll');
    MyProc := TMyProc(GetProcedureAddress(DllHandle, 'ShowText'));
    MyProc('Blubb');
  finally
    UnloadLibrary(DllHandle);
  end;
end;


Läuft alles auch sehr gut. Aber ich weiß natürlich nicht, ob das auch mit deinem Konstrukt funktioniert.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

MmVisual
Beiträge: 1445
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: DLL erstellen, mit Formular.

Beitrag von MmVisual »

Was macht das "UnloadLibrary"?
Bei Windows müsste dies in der Regel auch die Win API Funktion CloseHandle(THandle); aufrufen. Ein UnloadLibrary() habe ich nicht.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: DLL erstellen, mit Formular.

Beitrag von Socke »

MmVisual hat geschrieben:Was macht das "UnloadLibrary"?
Bei Windows müsste dies in der Regel auch die Win API Funktion CloseHandle(THandle); aufrufen. Ein UnloadLibrary() habe ich nicht.

Nein, CloseHandle() kann zwar eine ganze Menge Handle-Typen bearbeiten, aber keine Bibliotheken. Das geht bei Windows mit der Funktion FreeHandle(). Vergleiche in der MSDN-Deklaration auch die unterschiedlichen Typen HANDLE und HMODULE.

Free Pascal stellt mit der Unit dynlibs plattformunabhängige Funktionen bereit, um mit Bibliotheken zu arbeiten. So auch die Funktion UnloadLibrary().
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

MmVisual
Beiträge: 1445
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: DLL erstellen, mit Formular.

Beitrag von MmVisual »

Danke für den Tipp! Jetzt klappt das richtig.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Antworten