![]() |
Kommunikation zwischen DLL und Hauptprogramm
Hallo zusammen,
ich habe ein kleines Beispielprogramm mit einer DLL erstellt. Ich möchte, dass die Funktion TestSub aus der DLL auf eine Funktion der Klasse TMyClass im Hauptprogramm zugreift und entsprechend der übergebenen Werte rechnet. Hier mal der Sourcecode dazu. Hauptprogramm :
Delphi-Quellcode:
Unit mit dem Interface :
unit Unit2;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, AdvEdit, Unit3; type TForm2 = class(TForm) AdvEdt_Number1: TAdvEdit; AdvEdt_Number2: TAdvEdit; Btn_Addition: TButton; L_1: TLabel; L_2: TLabel; procedure Btn_AdditionClick(Sender: TObject); private { Private declarations } public { Public declarations } end; function TestSub(Number1, Number2: Integer): Integer; external 'Project3.dll'; var Form2: TForm2; implementation uses Unit1; {$R *.dfm} procedure TForm2.Btn_AdditionClick(Sender: TObject); var Number1: Integer; Number2: Integer; MyClass: TMyClass; begin if (TryStrToInt(AdvEdt_Number1.Text, Number1)) and (TryStrToInt(AdvEdt_Number2.Text, Number2)) then begin MyClass := TMyClass.Create; try L_1.Caption := IntToStr(MyClass.Add(Number1, Number2)); L_2.Caption := IntToStr(TestSub(Number1, Number2)); finally MyClass.Free; end; end; end; end.
Delphi-Quellcode:
Die Project3.dll :
unit Unit3;
interface type IMath = interface(IInterface)['{605A9672-328D-4A62-BBD3-7E07CEC01546}'] function Add(sum1, sum2: Integer): Integer; stdcall; function Sub(sub1, sub2: Integer): Integer; stdcall; end; implementation end.
Delphi-Quellcode:
Wenn ich das Programm ausführe und auf den Button klicke bekomme ich folgende Fehlermeldung :
library Project3;
{ Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } uses System.SysUtils, System.Classes, Unit3 in 'Unit3.pas'; {$R *.res} function TestSub(Number1, Number2: Integer): Integer; var MyClass : IMath; begin Result := MyClass.Sub(Number1, Number2); end; exports TestSub; begin end. --------------------------- Debugger Exception Notification --------------------------- Project Project2.exe raised exception class $C0000005 with message 'access violation at 0x00bc579f: read of address 0x00000000'. --------------------------- Break Continue Help --------------------------- Klicke ich jetzt auf Break, springt die IDE auf die Zeile
Delphi-Quellcode:
in der Project3.dll. Ich weiß nur nicht warum ? Was habe ich mal wieder vergessen ?
Result := MyClass.Sub(Number1, Number2);
Die Unit1 mit der Klasse :
Delphi-Quellcode:
Ein paar Links, wo ich mir ein paar Hintergrundinfos herauslesen kann, wären nicht schlecht. Ich habe zum Thema Interface, DLL und Hauptprogramm Kommunikation gefunden. Wahrscheinlich wieder die falschen Suchbegriffe eingegeben.
unit Unit1;
interface uses Unit3; type TMyClass = class(TInterfacedObject, IMath) public function Add(sum1, sum2: Integer): Integer; stdcall; function Sub(sub1, sub2: Integer): Integer; stdcall; end; implementation { TMyClass } function TMyClass.Add(sum1, sum2: Integer): Integer; begin Result := sum1 + sum2; end; function TMyClass.Sub(sub1, sub2: Integer): Integer; begin Result := sub1 - sub2; end; |
AW: Kommunikation zwischen DLL und Hauptprogramm
Wo gibst du der DLL denn ein implementiertes Interface?
MyClass in der DLL ist nil (oder noch schlimmer mit irgendwas belegt, weil nicht initialisiert). Was erwartest du also, wo da eine Instanz herkommen soll? |
AW: Kommunikation zwischen DLL und Hauptprogramm
Delphi-Quellcode:
Das Problem war, dass das Interface nicht an die DLL übergeben wurde. Ich habe die obenstehende Funktion einfach um den Parameter
library Project3;
{ Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } uses System.SysUtils, System.Classes, Unit3 in 'Unit3.pas'; {$R *.res} function TestSub(Number1, Number2: Integer): Integer; var MyClass : IMath; begin Result := MyClass.Sub(Number1, Number2); end; exports TestSub; begin end.
Delphi-Quellcode:
erweitert und die lokale Variable entfernt. Wenn ich jetzt die erstellte Klasse MyClass an die DLL-Funktion übergebe, funktioniert der Aufruf der Funktion TestSub.
MyIntf: IMath
Erst wenn ich das
Delphi-Quellcode:
in der Unit2 durch
MyClass.Free
Delphi-Quellcode:
ersetze, bekomme ich nichtmehr die folgende Fehlermeldung :
MyClass := nil;
--------------------------- Project2 --------------------------- Access violation at address 00000000. Read of address 00000000. --------------------------- OK --------------------------- |
AW: Kommunikation zwischen DLL und Hauptprogramm
Zitat:
|
AW: Kommunikation zwischen DLL und Hauptprogramm
In der Unit2 die Variable MyClass als IMath deklarieren, sonst haust du dir die Referenzzählung durcheinander.
Und ein Interface wird nicht freigegeben, sondern die Referenz auf nil gesetzt ;) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:40 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 by Thomas Breitkreuz