AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

DLL Problem mit XE7

Ein Thema von helste · begonnen am 8. Apr 2015 · letzter Beitrag vom 9. Apr 2015
 
helste

Registriert seit: 16. Jul 2009
72 Beiträge
 
Delphi 10.1 Berlin Professional
 
#6

AW: DLL Problem mit XE7

  Alt 8. Apr 2015, 16:34
Ich konnte jetzt ein Szenarium erstellen, welches den Fehler bringt.
Das Ergebnis ist merkwürdig.

So sieht die DLL aus:

Code:
library testdll;

uses
  System.SysUtils,
  System.Classes,
  Winapi.Windows,
  dlltestunit in 'dlltestunit.pas' {Form1};

{$R *.res}

function edittest : HWND; stdcall;

begin
result := edit_test;
end;


exports
  edittest;

begin
end.

In der dlltestunit habe ich ein Formular, auf welches ich Datenbankkomponenten von IBDAC platziert habe. Dazu noch eine TFileSaveDialog Komponente.
Dann noch 3 Schalter, welche unterschiedliche Aktionen ausführen.

Der Source sieht dann so aus:

Code:
unit dlltestunit;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Data.DB, MemDS, DBAccess,
  IBC;

type
  TForm1 = class(TForm)
    FileSaveDialog1: TFileSaveDialog;
    Button1: TButton;
    Label1: TLabel;
    IBCConnection1: TIBCConnection;
    IBCTransaction1: TIBCTransaction;
    IBCQuery1: TIBCQuery;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

function edit_test : HWND;

implementation

{$R *.dfm}

function edit_test : HWND;

var
  Form1: TForm1;

begin
result := 0;
Form1 := TForm1.Create (nil);
if assigned (Form1) then
   begin
   result := Form1.Handle;
   Form1.Show;
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
IBCQuery1.Open;
if not IBCQuery1.Eof then
   Label1.Caption := IBCQuery1.FieldByName('testfield').AsString;;
IBCQuery1.Close;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if FileSaveDialog1.Execute then
   Label1.Caption := FileSaveDialog1.FileName;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
if FileSaveDialog1.Execute then
   begin
   Label1.Caption := FileSaveDialog1.FileName;
   IBCQuery1.Open;
   if not IBCQuery1.Eof then
      Label1.Caption := Label1.Caption + ' - ' + IBCQuery1.FieldByName('testfield').AsString;;
   IBCQuery1.Close;
   end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
IBCQuery1.SQL.Text := 'Select testfield from testtable';
end;

end.

Im Rufenden Programm habe ich ebenfalls eine kleine Maske gemacht, auf der sich 3 Schalter befinden.
Die clicke ich dann der Reihe nach an, wodurch zuerst die DLL initiailsiert wird, dann die Funktion aufgerufen wird (maske der DLL wird angezeigt und da wird dann einer der 3 Schalter gedrückt). Anschließend wird die Maske der DLL geschlossen und im rufenden Programm der 3 Button gedrückt um die DLL wieder frei zu geben.
Dann wird das Programm beendet.

Hier nun noch das rufende Programm (bzw. die Unit mit dem Form).

Code:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Menus, StdCtrls;

type
  Tmain = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
     h       : HWND;
     testdll : HMODULE;
     edittest : function : HWND; stdcall;
  end;

var
  main: Tmain;

implementation

{$R *.dfm}


procedure Tmain.Button1Click(Sender: TObject);

begin
testdll := LoadLibrary('testdll.dll');
if testdll <> 0 then
   begin
   @edittest := GetProcAddress(testdll, 'edittest');
   end;
end;

procedure Tmain.Button2Click(Sender: TObject);

begin
if h = 0 then
   h := edittest
else
   ShowWindow(h, SW_SHOWNORMAL);
end;

procedure Tmain.Button3Click(Sender: TObject);

begin
FreeLibrary(LHnd);
edittest := nil;
end;

end.
Ich hoffe, das ist soweit verständlich.

Ich beobachte nun folgendes:

Drückt man in der aufgerufenen Maske (die aus Unit dlltestunit, also aus der aufgerufenen DLL Funktion) jeweils einen Button und beendet dann, dann passiert folgendes.
Bei Button1 und Button2 läuft alles völlig normal ab.
bei Button3 jedoch, läuft auch alles normal bis zum beenden des Hauptprogrammes. Das bleibt dann nämlich hängen und muss in der IDE durch den Programm abbrechen Button beendet werden. Startet man es außerhalb der IDE muss man den Taskmanager bemühen.

Es sieht also so aus: Ein Datenbankaufruf alleine macht nichts. FileSaveDialog1.Execute alleine macht ebenfalls nichts. Beides zusammen bringt Probleme.

Das ist nur eines von vielen Beispielen, wo das Problem auftritt. Einfaches Weglassen von FileSaveDialog1.Execute bringt mich also nicht weiter. In anderen Modulen ist es wieder ganz was anderes.

Jemand eine Idee?
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:05 Uhr.
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