OK, mal schnell heruntergeschludert (kann also noch Denkfehler enthalten, funktionierte aber bei einem schnellen Test): zunächst ein Interface mit einer Property nebst Getter und Setter und einer Methode.
Delphi-Quellcode:
unit TestIntf;
interface
uses System.Classes;
type
ITestIntf =
interface
['
{AE7A35E3-5DB3-4DEB-A817-E452DD62301C}']
function GetItems: TStrings;
stdcall;
procedure SetItems(
const Value: TStrings);
stdcall;
procedure ShowContents;
stdcall;
property Items: TStrings
read GetItems
write SetItems;
end;
implementation
end.
Dieses Interface wird sowohl in der
DLL als in der Exe benutzt. Jetzt zur
DLL, Klassenunit:
Delphi-Quellcode:
unit DLLClass;
interface
uses TestIntf, System.Classes;
type
TTest =
class(TInterfacedObject, ITestIntf)
strict private
FItems: TStrings;
public
function GetItems: TStrings;
stdcall;
procedure SetItems(
const Value: TStrings);
stdcall;
procedure ShowContents;
stdcall;
property Items: TStrings
read GetItems
write SetItems;
end;
function GetTest: ITestIntf;
stdcall;
implementation
uses Vcl.Dialogs;
function GetTest: ITestIntf;
stdcall;
begin
Result := TTest.Create;
end;
{ TTest }
function TTest.GetItems: TStrings;
begin
Result := FItems;
end;
procedure TTest.SetItems(
const Value: TStrings);
begin
FItems := Value;
end;
procedure TTest.ShowContents;
var
s:
string;
begin
if Assigned(FItems)
then
s := FItems.Text
else
s := '
< Keine Items zugewiesen >';
ShowMessage(s);
end;
end.
Das ist also eine minimale Klasse, die das Interface imlementiert. Zu beachten ist auch die Funktion GetTest, diese wird in der Hauptunit der
DLL exportiert.
Delphi-Quellcode:
library IntfDLL;
uses
DLLClass in 'DLLClass.pas';
{R *.res}
exports
GetTest;
begin
end.
In der Exe habe ich dann diese
DLL einfach statisch gebunden:
Delphi-Quellcode:
unit ExeMain;
interface
uses
Winapi.Windows,
Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs, TestIntf,
Vcl.StdCtrls;
type
TfrmDLLTestMain =
class(TForm)
btnCallIntf: TButton;
procedure btnCallIntfClick(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
frmDLLTestMain: TfrmDLLTestMain;
implementation
{$R *.dfm}
function GetTest: ITestIntf;
stdcall;
external '
IntfDLL.dll'
name '
GetTest';
procedure TfrmDLLTestMain.btnCallIntfClick(Sender: TObject);
var
List: TStringList;
Test: ITestIntf;
begin
Test := GetTest;
List := TStringList.Create;
try
List.Add('
Das');
List.Add('
ist');
List.Add('
das');
List.Add('
Haus');
List.Add('
vom');
List.Add('
Nikolaus');
// Einmal vor der Zuweisung
Test.ShowContents;
Test.Items := List;
// Und einmal nachher
Test.ShowContents;
finally
List.Free;
end;
end;
end.
Und nur der Vollständigkeit halber noch die *.dpr, da steht auch keine Magic drin:
Delphi-Quellcode:
program IntfTest;
uses
Vcl.Forms,
ExeMain
in '
ExeMain.pas'
{frmDLLTestMain};
{$R *.res}
begin
ReportMemoryLeaksOnShutdown := true;
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TfrmDLLTestMain, frmDLLTestMain);
Application.Run;
end.