Einzelnen Beitrag anzeigen

Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#27

AW: Übergabe einer Klasse von EXE an DLL

  Alt 25. Nov 2017, 12:32
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; // Meiner Meinung nach böse eine Klasse zu übergeben wenn auch abstract
  end;

implementation

end.
Einspruch!!
Das ist kein gutes Design. Du mixt hier Interfaces und Implementation

Durch
 property Items: TStrings read GetItems write SetItems; bist Du an einen Compiler gebunden.
Ein Interface sollte nur solche benutzen.

Delphi-Quellcode:
unit myInterfaces;

interface
   uses System.Classes;

type
  // Wenn wir nur über Window sprechen ist Dies ein Ansatz:
  IStringList = interface
     ['{143A95EE-EEEA-4F7F-97CC-7986EBAC17A5}']
     function AddString(const Value: WideString): Integer; stdcall;
     function GetCount: Integer; stdcall;
     function GetItems(Index: Integer): WideString; stdcall;
     procedure SetItems(Index: Integer; const Value: WideString); stdcall;
     property Count: Integer read GetCount;
     property Items[Index: Integer]: WideString read GetItems write SetItems;
  end;

   // Für non Windows müssen wir auf PlainData ztrückgreifen
   ICharBufferInterface = interface
    ['{D6CAF8DE-7792-4162-B472-E9F0A2410201}']
    procedure SetBuffer(const Buffer: PWideChar; Len : integer); stdcall;
    procedure GetBuffer(const Buffer: PWideChar; Len : integer); stdcall;
    function BufferLen : integer;
  end;

  IBufferList = interface
     ['{6FCA6674-3BE2-4D02-A078-F3142B1A41C1}']
     function GetCount: Integer; stdcall;
     function GetItems(Index: Integer): ICharBufferInterface; stdcall;
     procedure SetItems(Index: Integer; Value: ICharBufferInterface); stdcall;
     property Count: Integer read GetCount;
     property Items[Index: Integer]: ICharBufferInterface read GetItems write SetItems;
     function AddItem: ICharBufferInterface; stdcall;
  end;

implementation

end.
Hier noch eine mögliche implementierung einer Klasse dazu:

Delphi-Quellcode:
unit myImplementation;

interface
    uses System.Classes,
         myInterfaces;


 type TMyWideStringListImpl = class(TInterfaceList, IStringList)

 private
    fList : TStringList;
    function checkIndex(index : integer) : boolean; inline;

  private // From IStringList
    function AddString(const Value: WideString): Integer; stdcall;
    function GetCount: Integer; stdcall;
    function GetItems(Index: Integer): WideString; stdcall;
    procedure SetItems(Index: Integer; const Value: WideString); stdcall;

  public
    constructor Create;
    destructor Destroy; override;
 end;

implementation

function TMyWideStringListImpl.AddString(const Value: WideString): Integer;
begin
   result := flist.Add(Value);
end;

function TMyWideStringListImpl.GetCount: Integer;
begin
   result := fList.Count;
end;

function TMyWideStringListImpl.GetItems(Index: Integer): WideString;
begin
 if checkindex(index) then
  result := Flist[Index]
  else result := '';
end;


procedure TMyWideStringListImpl.SetItems(Index: Integer; const Value: WideString);
begin
   Flist[Index] := Value;
end;

constructor TMyWideStringListImpl.Create;
begin
  inherited;
  fList := TStringList.create;
end;

destructor TMyWideStringListImpl.Destroy;
begin
  fList.free;

  inherited;
end;

function TMyWideStringListImpl.checkIndex(index: integer): boolean;
begin
   result := (index >= 0) and (index<Flist.count);
end;

end.
Fritz Westermann
  Mit Zitat antworten Zitat