AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Übergabe einer Klasse von EXE an DLL

Ein Thema von norwegen60 · begonnen am 18. Sep 2017 · letzter Beitrag vom 29. Nov 2017
Antwort Antwort
Seite 1 von 3  1 23      
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
504 Beiträge
 
Delphi 12 Athens
 
#1

Übergabe einer Klasse von EXE an DLL

  Alt 18. Sep 2017, 08:08
Hallo zusammen,

ich habe schon diverse Beiträge zu dem Thema gefunden, aber die Angaben sind widersprüchlich.

Ich habe folgende stark vereinfachte Klassendefinition
Delphi-Quellcode:
type
  TMesswert = class(TObject)
    Belastung : Real;
    Strom : Real;
  end;

  TMesswertListe = class( TObjectList<TMesswert> )
  public
    constructor Create( OwnsObjects: Boolean = true );
  end;

  TAnalyse = class(TObject)
  private
    FNr : Integer;
    FStatus : Integer; // In Wirklichkeit Enum
    FTitel : String;
    FTestunit : String;
    FMesswerte : TMesswertList;
  public
    property FNr : Integer read Nr write Nr ;
    property FTitel : String read Titel write Titel ;
    property FTestunit : String read Testunit write Testunit ;
    constructor Create;
    destructor Destroy; override;
  end;

  TAnalyseList = class(TObjectList<TAnalyse> )
  private
    function Compare( const L,R: TAnalyse) : Integer;
  public
    constructor Create( OwnsObjects: Boolean = true );
  end;

  TBatch = class(TObject)
  private
    FNr : Integer;
    FAnalysen : TAnalyseList;
  public
    property FNr : Integer read Nr write Nr ;
    constructor Create;
    destructor Destroy; override;
  end;
Im angedachten Fall soll
  • eine DLL aufgerufen und dieser die komplette Instanz von TBatch übergeben werden.
  • Die EXE erzeugt für jede gewünschte Belastung einen Eintrag in TMesswertList
  • Nach der Übergabe von TBatch an die DLL soll diese anhand von Testunit die korrekte Testunit starten und dann für jede Belastung den zugehörigen Strom messen und in der Liste eintragen.
  • Sobald fertig, wird der Status von TAnalyse auf asMeasured gesetzt und EXE weiß, dass sie jetzt damit weiter machen kann.
  • Testunit ist in Wirklichkeit eine weitere Klasse (Gerät, Schnittstelle, ...)
  • Es sollte auch möglich sein, dass die EXE eine weitere Analyse an TBatch anhängt während die DLL die schon eingetragenen Analysen abarbeit. Auch diese neue Analyse wird von DLL automatisch vermessen.

Es bestehen folgende Voraussetzungen
  • Die Klasse wird in der EXE angelegt
  • Werte sollen sowohl in der EXE als auch der DLL geändert werden
  • EXE und DLL werden bei jeder Änderung in exakt derselben Umgebung kompiliert
  • Auf Mitgabe von Packages soll wenn möglich verzichtet werden
  • Entwicklungsumgebung Delphi XE

Mein Problem ist nur die Frage, wie ich die Klasse korrekt an die DLL übergeben muss damit beide Seiten darin arbeiten können.

Gibt es ein Möglichkeit, so was zu realisieren?
Mit Klassen fühle ich mich noch unsicher und mit Interfaces habe ich noch nie gearbeitet. Von daher wäre ich für eine konkrete Antwort, an liebsten mit Beispiel, sehr dankbar.

Grüße
Gerd
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Übergabe einer Klasse von EXE an DLL

  Alt 18. Sep 2017, 08:44
Entweder du arbeitest mit Run-Time-Packages, auf welche beide Seiten zugreifen, da Du dann auch einen gemeinsamen Memory-Manger nutzt. Dieses wäre die Voraussetzung, um Klassen über Prozessgrenzen hinweg zu nutzen.

Oder, Du stellst auf Interfaces um, diese kannst Du dann ohne größere Probleme zwischen beiden Seiten nutzen und übergeben.

......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Übergabe einer Klasse von EXE an DLL

  Alt 18. Sep 2017, 09:58
Wie Sakura schon sagte, ist ein Austausch von Objekt-Instanzen so nicht möglich. Aber, neben der Sache mit Interfaces, wäre auch ein anderer Ansatz denkbar.

Sowie ich das verstehe, ist der Zweck der DLL, die Liste der Analysen nacheinander durch zu ackern und die entsprechenden Tests auszuführen und je nach Ergebnis für jede Analyse einen entsprechenden Status zu setzen.

Wenn die DLL jetzt nicht grad noch von einer anderen Anwendung benutz werden soll, würd ich diese über die Klinge springen lassen und statt dessen die Analyse in einen eigenen Thread auslagern, sodas dieser quasi im Hintegergrund die Analyseliste immer wieder durcharbeiten kann. Wenn eine Analyse mit dem entsprechenden Status abegschlossen worden ist, kann der Thread das Hauptprogramm benachrichtigen. Genauso kann das Hauptprogramm neue
Analysen hinzufügen.

Das ganze ist jetzt mehr eine Idee/Denkanstoss, die ich hier mal so geschrieben hab.
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Fritzew

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

AW: Übergabe einer Klasse von EXE an DLL

  Alt 18. Sep 2017, 10:42
Zitat:
und statt dessen die Analyse in einen eigenen Thread auslagern
Wobei das wohl der einzige Ansatz ist der funktioniert. Da in einer Dll die Routinen ja auch im Main-Thread laufen,
braucht man sowieso einen extra Thread. Dann kann man das immer noch in eine DLL packen, zuerst sollte aber das "Problem" gelöst werden.
Fritz Westermann
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Übergabe einer Klasse von EXE an DLL

  Alt 18. Sep 2017, 10:45
Oder eventuell in eine komplett eigene Anwendung auslagern. Die Daten in einem gemeinsamen Format (JSON, XML, binär, ...) austauschen. Dann können die Prozesse komplett autonom arbeiten.

......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
504 Beiträge
 
Delphi 12 Athens
 
#6

AW: Übergabe einer Klasse von EXE an DLL

  Alt 18. Sep 2017, 11:01
Sowie ich das verstehe, ist der Zweck der DLL, die Liste der Analysen nacheinander durch zu ackern und die entsprechenden Tests auszuführen und je nach Ergebnis für jede Analyse einen entsprechenden Status zu setzen.

Wenn die DLL jetzt nicht grad noch von einer anderen Anwendung benutz werden soll, würd ich diese über die Klinge springen lassen und statt dessen die Analyse in einen eigenen Thread auslagern, sodas dieser quasi im Hintegergrund die Analyseliste immer wieder durcharbeiten kann. ...
Du hast es korrekt verstanden.
Über die DLL wollen wir aber den Messprozess weitgehend von der EXE kapseln. In der DLL soll er dann in einem eigenen Thread laufen.

Ein Kollege hat mal folgendes ausprobiert:

Hauptprogramm:

Delphi-Quellcode:
uses
  ...,
  clBatch;

type
  procedure ShowTestForm(aApplication: TApplication; aAnalyse: TAnalyse); stdcall; external 'DelphiDll.dll';

implementation
  ...

procedure TfoMain.btnShowDelphiDllClick(Sender: TObject);
var
  aAnalyse: TAnalyse;

begin
  aAnalyse := GetCurrentAnalyse;
  ShowTestForm(Application, aAnalyse);
end;
Und die DLL
Delphi-Quellcode:
library DelphiDll;

{ Important note about DLL memory management: ShareMem must be the
  ...}


uses
  ShareMem,
  clBatch,
  ...;

{$R *.res}

exports
  ShowTestForm;

begin
end.

unit uFormTest;
interface

uses
 ...

type
  TFormTest = class(TForm)
    EditAnalyse: TEdit;
    Label1: TLabel;
    btnAssFilled: TButton;
    btnAssInjected: TButton;
    procedure btnAssFilledClick(Sender: TObject);
    procedure btnAssInjectedClick(Sender: TObject);
  private
    { Private declarations }
    FAnalyse: TAnaylse;
    procedure SetAnalyse(aAnalyse: TAnalyse);
  public
    { Public declarations }
    constructor Create(AOwner: TComponent);
    class procedure ShowForm(aApplication: TApplication; aAnalyse: TAnalyse);
  end;


implementation

{$R *.dfm}

uses
  ...;

var
  dllApplication: TApplication=nil;
  FormTest: TFormTest=nil;

procedure TFormTest.btnAssFilledClick(Sender: TObject);
begin
  if not Assigned(FAnalyse) then exit;
  FAnalyse.Status := assFilled;
end;

procedure TFormTest.btnAssInjectedClick(Sender: TObject);
begin
  if not Assigned(FAnalyse) then exit;
  FAnalyse.Status := assInjected;
end;

constructor TFormTest.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FAnalyse:= nil;
end;

procedure TFormTest.SetSample(aAnalyse: TAnalyse);
begin
  FAnalyse:= aAnalyse;
end;

class procedure TFormTest.ShowForm(aApplication: TApplication; aAnalyse: TAnalyse);
begin
  if not Assigned(dllApplication) then
  begin
    dllApplication:= Application;
  end;
  Application := aApplication;
  if not Assigned(FormTest) then
    FormTest := TFormTest.Create(Application);
  FormTest.FAnalyse := aAnalyse;
  if not Assigned(aAnalyse) then
    FormTest.EditAnalyse.Text := '-'
  else
    ;// EditAnalyse.Text := aAnalyse.name;
  { TODO :
    Mit der auskommentierten Zeile gibt es im folgenden eine Exception "Invalid pointer operation ..."
    was irgendetwas mit strings zu tun hat. Richtig angezeigt wird der Name dennoch.
    Die Ursache ist zu ergründen.
  }

  FormTest.Show;
end;

initialization
begin
  dllApplication := nil;
end;

finalization
begin
  if Assigned(dllApplication) then Application := dllApplication;
end;


end.
und das funktioniert.

In der DLL wird ein Formular geöffnet und darin kann man den Status der Analyse ändern.

Fragt man in der EXE den Status ab, wird dort der korrekte (geänderte) Status angezeigt.

Von daher sieht es doch ganz einfach aus?
  Mit Zitat antworten Zitat
Fritzew

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

AW: Übergabe einer Klasse von EXE an DLL

  Alt 18. Sep 2017, 11:13
Das wird so nicht funktionieren. Kapselt als erstes Euere Analyse sauber in einen Thread.
Das dann in eine DLL zu packen ist in meinen Augen der 2. Schritt.
class procedure TFormTest.ShowForm(aApplication: TApplication; aAnalyse: TAnalyse); Das fliegt Euch früher oder später um die Ohren ohne Packages. Da das TApplication und TAnalyse in der EXE und DLL unterschiedlich sind. (verschiedene Vmt's etc).....
Entweder Packages, Interfaces oder eine gute alte c-schnittstelle
Fritz Westermann
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: Übergabe einer Klasse von EXE an DLL

  Alt 18. Sep 2017, 15:08
Alternativen dazu wären natürlich die "Old-School" Methode mit Records, Zeigern und Zeigerketten. Die kann man ohne Probleme zwischen Exe und DLL austauschen


Bsp.: (He..das is nur so ungefähr) :
Delphi-Quellcode:
TYPE
   PMesswert = ^TMesswert;
   TMesswert = Record
       Belastung, Strom : Real;
       Prev,Next : PMesswert;
   end;
   PAnalyse = ^TAnalyse;
   TAnalyse = Record
     Nr,Status : Integer;
     Titel,TestUnit : String;
     Messwerte : PMesswerte; //Zeiger auf den Anfang der Zeigerkette;
   end;
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
504 Beiträge
 
Delphi 12 Athens
 
#9

AW: Übergabe einer Klasse von EXE an DLL

  Alt 18. Sep 2017, 16:24
Alternativen dazu wären natürlich die "Old-School" Methode mit Records, Zeigern und Zeigerketten. Die kann man ohne Probleme zwischen Exe und DLL austauschen
Die Klassenstruktur besteht schon. Die zurück zu ändern wäre ein sehr großer Eingriff

Das wird so nicht funktionieren. Kapselt als erstes Euere Analyse sauber in einen Thread.
Der Thread ist eine Sache, die Datenübergabe eine andere. Mir geht es in dieser Anfrage nur darum "Wie kann ich innerhalb Delphi eine Klasse übergeben" bzw. was ist an unserem Ansatz falsch.

Ich habe jetzt mal das Beispiel von meinem Kollegen auf das minimiert, was man für einen ersten Test braucht. Auch wenn die Aussage im Raum steht, dass uns das um die Ohren fliegt...
Wo ist das Problem? Ein anderer Programmierer hat dazu gemein, dass eine Klasse innerhalb Delphi auch nur ein Pointer ist und wenn beide Seiten über den Aufbau genau das gleiche wissen, würden beide auch gleich mit den Daten umgehen.
Ich kann sehr gut damit leben, wenn in der DLL nur die Daten zur Verfügung stehen und eventuelle Methoden tabu sind. Man muss vielleicht noch dazu sagen, dass die EXE nur noch lesend auf die Messwert-Liste zugreift.

Ich habe mal das lauffähige Porjekt als ZIP angehängt. Ich wäre echt dankbar, wenn man einen Weg finden würde, das Ganze sicher zum Laufen zu bringen. Oder zu zeigen, wo die Fallstricke im Betrieb sind

In dem Projekt kann man
  • eine Klasse mit zufälliger Unterstruktur erzeugen
  • diese in einem TreeView darstellen
  • im TreeView eine Analyse markieren
  • Diese an die DLL übergeben
  • dort den Status ändern
  • über [Read Analysis] die Änderung des Status im TreeView darstellen
Letzteres könnte man natürlich über CallBacks noch eleganter lösen aber im Moment geht es um die Klassenübergabe

Auch wenn ihr jetzt denkt "Wenn du uns nicht glaubst, dann lass es doch bleiben" Das ist es nicht. Aber vielleicht finde ich den, der mir sagt, so und so würde es gehen Es ist immer schwer von etwas abzulassen, wenn es irgendwie schon funktioniert. Gleichzeitig weiß ich aber, dass das Zufall sein kann und sich ganz schnell ändern kann.
Angehängte Dateien
Dateityp: zip ClassToDLL.zip (174,7 KB, 4x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#10

AW: Übergabe einer Klasse von EXE an DLL

  Alt 18. Sep 2017, 16:37
Auch wenn die Aussage im Raum steht, dass uns das um die Ohren fliegt...
Wo ist das Problem? Ein anderer Programmierer hat dazu gemein, dass eine Klasse innerhalb Delphi auch nur ein Pointer ist und wenn beide Seiten über den Aufbau genau das gleiche wissen, würden beide auch gleich mit den Daten umgehen.
Solange du DLL und EXE mit exakt der gleichen Delphi Version kompilierst, "sollte" es funktionieren. Ob da nicht am Ende doch bei RTTI lastigen Anwendungen irgendwas um die Ohren fliegt, kann ich allerdings nicht genau sagen.

Edit: Wobei .. wenn ich grade nochmal so drüber nachdenke, dann könnte es diverse statische Speicherbereiche bzw. Singletons geben, die dann zwischen DLL und EXE nicht geshared werden würden. Das kann auch Probleme machen.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl (18. Sep 2017 um 16:39 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 06:26 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz