TZConnection in DLL

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
php_Teufel
Beiträge: 4
Registriert: Mo 26. Nov 2012, 10:37

TZConnection in DLL

Beitrag von php_Teufel »

Hallo alle zusammen,

habe da ein Problem, an dem ich schon längere Zeit herum bastele.

Ich habe ein Programm(Menue), das Module(DLL's) dynamisch aufruft und um nicht für jede DLL eine eigene Datenbankverbindung aufzubauen wird ein Pointer auf die Connection-Componente(Zeos) im Menue weitergegeben.

Soweit so gut, ich kann Tabellen der Datenbank in den DLL's öffnen und bearbeiten. :D

Sobald ich allerdings die Connection-Componente im Modul auf NIL setze, oder das Hauptprogramm schließe, erhalte ich einen SIGSEGV-Fehler. :(

Kann mir jemand erklären was ich falsch mache, oder was ich noch beachten muss :?:

Vielen Dank

Volker

Socke
Lazarusforum e. V.
Beiträge: 3177
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: TZConnection in DLL

Beitrag von Socke »

php_Teufel hat geschrieben:Sobald ich allerdings die Connection-Componente im Modul auf NIL setze, oder das Hauptprogramm schließe, erhalte ich einen SIGSEGV-Fehler. :(

Kann mir jemand erklären was ich falsch mache, oder was ich noch beachten muss :?:
Ohne Quelltext sind konkrete Vorschläge leider nicht möglich. Es sieht ganz danach aus, als ob die Verbindung noch in einem der Module verwendet wird, obwohl sie bereits freigegeben wurde.

Was dabei hilft, ist eine strikte Definition wer was wann instantiiert (Hauptprogramm, Datenbankverbindung, Module, ...) und wann was von wem wieder freigegeben wird. Logischerweise muss die Deinitialisierung in umgekehrter Reihenfolge ablaufen, sofern man die Verbindungen zwischen den einzelnen Komponenten nicht gesondert behandelt.

Für dich heißt das in etwa: Das Hauptprogramm wird vom Betriebssystem (aka Benutzer) gestartet und stellt eine Datenbankverbindung her. Danach werden die Module geladen.
Beim Beenden werden zuerst die Module entladen, dann die Datenbankverbindung abgebaut und schlussendlich das Hauptprogramm aufgeräumt und beendet.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

php_Teufel
Beiträge: 4
Registriert: Mo 26. Nov 2012, 10:37

Re: TZConnection in DLL

Beitrag von php_Teufel »

Hier der entsprechende Code:

DLL:

Code: Alles auswählen

 
library gem001;
 
{$mode DELPHI}{$H+}
 
uses
  Classes, Interfaces, Land, zcomponent, ZConnection, Forms;
procedure Start(db: Pointer);
var pDB:^TZConnection;
begin
  pDB:=db;
  application.CreateForm(TfrmGEM001,frmGEM001);
  frmGEM001.ZTable1.Connection:=pDB^;
  frmGEM001.ShowModal;
end;
exports
  Start;
begin
  Application.Initialize;
end.
unit Land;
 
{$mode DELPHI}{$H+}
 
interface
 
uses
  Classes, SysUtils, db, FileUtil, ZConnection, ZDataset, Forms, Controls,
  Graphics, Dialogs, DBGrids;
 
type
 
  { TfrmGEM001 }
 
  TfrmGEM001 = class(TForm)
    Datasource1: TDatasource;
    DBGrid1: TDBGrid;
    ZTable1: TZTable;
    ZTable1Bezeichnung: TStringField;
    ZTable1EU: TBooleanField;
    ZTable1Land: TStringField;
    ZTable1Vorwahl: TStringField;
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormShow(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  frmGEM001: TfrmGEM001;
implementation
 
procedure TfrmGEM001.FormShow(Sender: TObject);
begin
 
  ZTable1.Active:=true;
end;
 
procedure TfrmGEM001.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  ztable1.Active:=false;
  ztable1.connection:=nil;
  closeaction:=caFree;
end;
 
 
{$R *.lfm}
 
{ TfrmGEM001 }
 
 
end.
 
Hauptprogramm:

Code: Alles auswählen

 
unit uMenue;
 
{$mode Delphi}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  DynLibs, ZConnection;
 
type
  ProcStart = procedure(var db: Pointer);
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    ZConnection1: TZConnection;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
  hnd: TLibHandle;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
var
  proc: ProcStart;
begin
  hnd := LoadLibrary('gem001.dll');
  @proc := GetProcedureAddress(hnd, 'Start');
  proc(@ZConnection1);
end;
 
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  unloadlibrary(hnd);
  closeaction:=cafree;
end;
 
 
end.
 

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

Re: TZConnection in DLL

Beitrag von MmVisual »

Ein Formular in der DLL auf zu rufen ist sehr Trickreich.

Ich bin mir nicht sicher, ich meine es muss das Handle der Main-Applikation übergeben werden und darauf das DLL Formular erstellt werden.
EleLa - Elektronik Lagerverwaltung - www.elela.de

EgonHugeist
Beiträge: 93
Registriert: Di 17. Apr 2012, 22:41

Re: TZConnection in DLL

Beitrag von EgonHugeist »

Habe da so 'ne Ahnung..

Könnte an der Reistrierung/Deregistrierung der DataSets liegen. Werd mich mal drum kümmern.

Gruß Michael

ZeosDevTeam
ZeosDevTeam

Antworten