Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
Delphi 10 Seattle Enterprise
|
AW: DLL Exportiert ein Interface mit Strings...
11. Jun 2014, 14:25
Und hier mal komplett zusammengebaut:
- DLL
Delphi-Quellcode:
library dp_180689_lib;
uses
System.SysUtils,
ExternalClassLibWrapper in 'ExternalClassLibWrapper.pas',
ExternalClassIntf in 'ExternalClassIntf.pas',
ExternalClass in 'lib\ExternalClass.pas';
{$R *.res}
function GetExternalClassWrapper : IExternalClassWrapper; safecall;
begin
Result := TExternalClassWrapper.Create;
end;
exports
GetExternalClassWrapper;
begin
end.
- die originale Unit (liegt nur als DCU vor)
Delphi-Quellcode:
unit ExternalClass;
// originale Unit, die nicht geändert werden kann,
// da diese nur als DCU vorliegt
interface
uses
Classes;
type
TExternalClass = class
public
procedure DoSomething( AStream : TStream );
end;
implementation
{ TExternalClass }
procedure TExternalClass.DoSomething( AStream : TStream );
var
LWriter : TStreamWriter;
begin
LWriter := TStreamWriter.Create( AStream );
try
LWriter. Write( ' Written by ExternalClass' );
finally
LWriter.Free;
end;
end;
end.
- Der Wrapper für die Klasse und das Interface
Delphi-Quellcode:
unit ExternalClassLibWrapper;
interface
uses
ActiveX, Classes, Vcl.AxCtrls,
ExternalClassIntf, ExternalClass;
type
TExternalClassWrapper = class( TInterfacedObject, IExternalClassWrapper )
private
FInstance : TExternalClass;
public
constructor Create;
destructor Destroy; override;
procedure DoSomething( AStream : IStream ); safecall;
end;
implementation
{ TExternalClassWrapper }
constructor TExternalClassWrapper.Create;
begin
inherited Create;
FInstance := TExternalClass.Create;
end;
destructor TExternalClassWrapper.Destroy;
begin
FInstance.Free;
inherited;
end;
procedure TExternalClassWrapper.DoSomething( AStream : IStream );
var
LStream : TStream;
begin
LStream := TOleStream.Create( AStream );
try
FInstance.DoSomething( LStream );
finally
LStream.Free;
end;
end;
end.
- Das Interface (das teilen sich sowohl DLL als auch die Anwendung)
Delphi-Quellcode:
unit ExternalClassIntf;
interface
uses
ActiveX;
type
IExternalClassWrapper = interface
[' {9AC01751-00EB-49D8-9FBA-3BDB1EA5F2D9}']
procedure DoSomething( AStream : IStream ); safecall;
end;
implementation
end.
- Testprogramm
Delphi-Quellcode:
program dp_180689_app;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Classes,
ExternalClassIntf in ' ExternalClassIntf.pas',
ExternalClass in ' ExternalClass.pas';
procedure Main;
var
LStream : TStream;
LExternal : TExternalClass;
LReader : TStreamReader;
begin
LStream := TMemoryStream.Create;
try
LExternal := TExternalClass.Create;
try
LExternal.DoSomething( LStream );
finally
LExternal.Free;
end;
LStream.Seek( 0, soFromBeginning );
LReader := TStreamReader.Create( LStream );
try
Writeln( LReader.ReadToEnd );
finally
LReader.Free;
end;
finally
LStream.Free;
end;
end;
begin
ReportMemoryLeaksOnShutdown := True;
try
Main;
except
on E : Exception do
Writeln( E.ClassName, ' : ', E. Message );
end;
ReadLn;
end.
- Wrapper (Unit und Klasse folgen der selben Namenskonvention, dadurch spart man sich Tipparbeit)
Delphi-Quellcode:
unit ExternalClass;
interface
uses
Classes,
ExternalClassIntf;
type
TExternalClass = class
private
FInstance : IExternalClassWrapper;
public
constructor Create;
procedure DoSomething( AStream : TStream );
end;
implementation
uses
ActiveX;
function GetExternalClassWrapper : IExternalClassWrapper; safecall; external ' dp_180689_lib.dll' delayed;
{ TExternalClass }
constructor TExternalClass.Create;
begin
inherited Create;
FInstance := GetExternalClassWrapper;
end;
procedure TExternalClass.DoSomething( AStream : TStream );
begin
FInstance.DoSomething( TStreamAdapter.Create( AStream, soReference ) );
end;
end.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
|
|
Zitat
|