Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#28

AW: DLL Exportiert ein Interface mit Strings...

  Alt 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)
  Mit Zitat antworten Zitat