AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi DLL Exportiert ein Interface mit Strings...
Thema durchsuchen
Ansicht
Themen-Optionen

DLL Exportiert ein Interface mit Strings...

Ein Thema von Mavarik · begonnen am 9. Jun 2014 · letzter Beitrag vom 9. Apr 2017
Antwort Antwort
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.490 Beiträge
 
Delphi 12 Athens
 
#1

AW: DLL Exportiert ein Interface mit Strings...

  Alt 11. Jun 2014, 12:08
Ich muss an eine DLL 1-3 TStreams übergeben und diese an einen Procedure in der DLL weiterleiten... Was die Procedure damit macht kann ich nicht sagen.
Weiter oben hies es, du möchtest die Prozeduren einer DCU über eine DLL kapseln.
Der DLL kannst du IStream übergeben, die macht daraus mit ihrem eigenen Speichermanager wieder TStream und ruft damit die Procedure der DCU auf.
Das Beispiel weiter oben zeigt dabei alle Möglichkeiten auf, hier noch mal vereinfacht:
Delphi-Quellcode:
{dll-Funktion kapselt dcu}
function DllFunction(const Input, Output: IStream);
var
  InputStream: TStream;
  OutputStream: TStream;
begin
  InputStream := TOleStream.Create(Input);
  OutputStream := TOleStream.Create(Output);
  try
    {dcu-Funktion aufrufen}
    DcuFunction(InputStream, OutputStream); // <- erwartet TStream als Parameter
  finally
    InputStream.Free;
    OutputStream.Free;
  end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

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

AW: DLL Exportiert ein Interface mit Strings...

  Alt 11. Jun 2014, 13: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
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.879 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: DLL Exportiert ein Interface mit Strings...

  Alt 11. Jun 2014, 14:11
Markus Kinzler
  Mit Zitat antworten Zitat
Antwort Antwort


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 23:00 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-2025 by Thomas Breitkreuz