AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Plugins: Datenaustausch zwischen DLL und Hauptprogramm
Thema durchsuchen
Ansicht
Themen-Optionen

Plugins: Datenaustausch zwischen DLL und Hauptprogramm

Ein Thema von alleinherrscher · begonnen am 21. Okt 2009 · letzter Beitrag vom 27. Nov 2009
Antwort Antwort
Seite 3 von 3     123   
hanspeter

Registriert seit: 26. Jul 2003
Ort: Leipzig
1.350 Beiträge
 
Delphi XE2 Professional
 
#21

Re: Plugins: Datenaustausch zwischen DLL und Hauptprogramm

  Alt 27. Nov 2009, 08:27
Zitat von Elvis:
Weil ein unschuldiger Mitleser sonst den falschen Eindruck bekäme, dass Pseudo-Modularisierug mit Packages wirkliche Flexibilität bringen würde und einem nicht 70% der Haarpracht kostet.
Da muss ich Elvis aus leidvoller Erfahrung voll zustimmen. Ich halte die BPL für den größten Design Fehler in Delphi.
Arbeite ich nur mit Dll und verwende keine Laufzeitbibliotheken, dann lauert noch eine andere Falle.
Viele Componenten registrieren ihren Namen mit Registerclass bei Windows. Ist so eine Klasse einmal registriert, kann sie in keiner weiteren dll verwendet werden.
Bestes Beispiel dll A verwendet Fastreport. Alles geht.
Jetzt wird dll B geladen, die auch den Fastreport verwendet und es knallt. (Class bereits registriert.)
Einziger Ausweg sind hier runtime - dll. Die Nachteile wurden schon geschildert.
run-time bpl hat noch einen anderen Haken. Der Linker von >= D2007 scheint nicht mehr allzu smart zu sein.
Beim Programmstart verlangt ein Programm erst mal alle bpl, die bei der Compilierung nur in der Nähe des Programms waren.
Mit einem Programm mußte ich fast 90 bpl dazu kopieren.
Bestes Beispiel. Ich arbeite mit IBDAC, IBDAC ist TDataSource kompatibel. Über diese Hintertür erwartet das Programm, dass die BDE-Laufzeitbibliothek vorhanden ist.

Wenn man sauber modularisieren will, gibt es nach meiner Meinung in Delphi nur zwei Wege. Das ist einmal ein Comserver. Einmal registriert und er tut was er soll. (Einziger _Nachteil die Registrierung.)
Eine weitere Möglichkeit ist die Modularisierung auf Exe-Basis. Eine Exe wird mit Kommandozeilen - Optionen aufgerufen.
In der Kommandozeile übergebe ich das Handle des rufenden Programms. Damit ist eine einfache IPC möglich.
Mit D2010 probiere ich gerade eine IPC auf Basis von SOAP.
Es gibt von Remobjects das Framework Hydra. Bei der Modularisierung auf Delphi-Basis hat es ebenfalls alle bereits geschilderten Nachteile.
(Benötigt Laufzeit - dll)
Was es aber zufriedenstellend löst, ist die Einbindung von Net-Assembly in Delphi.
Ich übergebe beim Aufruf den Window-Parent und kann ein Fenster nahtlos in der Delphi-Applikation einfügen.
Diesen Weg erprobe ich gerade mit WPF, da ich im Moment für eine Firma ein Konzept zur schrittweisen Ablösung von Delphi erarbeite.
Hinterrgrund der Ablösung ist übrigens weniger Delphi selbst, sondern die Tatsache das es zunehmend Schwierigkeiten in 64 bit Umgebungen gibt und
Multiplattformfähigkeiten erwartet werden.
Die Möglichkeit von Net, die Pflege der Laufzeitbibliotheken an MS zu delegieren und diese (zumindest ab XP SP2) vorraussetzen zu können ist schon verlockend.
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#22

Re: Plugins: Datenaustausch zwischen DLL und Hauptprogramm

  Alt 27. Nov 2009, 10:24
Zitat von hanspeter:
Zitat von Elvis:
Weil ein unschuldiger Mitleser sonst den falschen Eindruck bekäme, dass Pseudo-Modularisierug mit Packages wirkliche Flexibilität bringen würde und einem nicht 70% der Haarpracht kostet.
Da muss ich Elvis aus leidvoller Erfahrung voll zustimmen. Ich halte die BPL für den größten Design Fehler in Delphi.
Sie machen Sinn für die IDE, sie machen keinen Sinn außerhalb der IDE.

Zitat:
Arbeite ich nur mit Dll und verwende keine Laufzeitbibliotheken, dann lauert noch eine andere Falle.
Viele Componenten registrieren ihren Namen mit Registerclass bei Windows.
Falsch, RegisterClass registriert esin der RTL. Und die kann man für jede DLL & Exe getrennt haben. Ohne Laufzeitpackages sind sie sogar immer getrennt.
Zitat:
Ist so eine Klasse einmal registriert, kann sie in keiner weiteren dll verwendet werden.
Bestes Beispiel dll A verwendet Fastreport. Alles geht.
Jetzt wird dll B geladen, die auch den Fastreport verwendet und es knallt. (Class bereits registriert.)
Wie gesagt: ohne Laufzeit-Packages hast du das Problem nicht. Aber du musst dann halt mit Interfaces arbeiten, nicht mit Delphi-Klassen.
Wenn du also ein Control auf dein Form aus einer DLL laden willst, musst du per SetParent dann das Control in den jeweiligen Container packen. Aber das kann man einmalig hübsch OO verpacken, so dass die DLL nur eine Interface-reference liefern muss, die das Control verpackt und die man dann einem anderen Control per SetParent as Child hinzufügt.
Für non-visuelle macht es mehr Sinn von vorn herein auch innerhalb der Exe auf einer Interface-basierte API aufzubauen.

Zum Beispiel sowas (aus den Fingern gesaugt)
Delphi-Quellcode:
var
  menu : IMenuProvider;
  menuItem : IMenuItem;
begin
  menu := Services.GetService(IMenuProvider) as IMenuProvider;
  menuItem := menu['Edit'].AddItem('Copy');
  menuItem.Caption := '&Copy';
  menuItem.Click := @CopyClickHandler;
end;
Auf die Art hat man genau die Art Dog-Fooding, die nötig ist damit Plugins genügend Möglichkeiten haben um wirklich sinnvoll zu sein. Denn wenn die API, die auch die Plugins nutzen, nicht mächtig genug ist, merkst du das schon während du deine HauptApp schreibst.
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
679 Beiträge
 
Delphi 10.4 Sydney
 
#23

Re: Plugins: Datenaustausch zwischen DLL und Hauptprogramm

  Alt 27. Nov 2009, 13:37
Zitat von Elvis:
Zitat von MyRealName:
Ich weiss nicht, warum Du mir widersprichst, sagst doch nur etwas gegen BPLs und ich rede davon, wie man DLLs nutzen kann mit Klassen drin.
Weil ein unschuldiger Mitleser sonst den falschen Eindruck bekäme, dass Pseudo-Modularisierug mit Packages wirkliche Flexibilität bringen würde und einem nicht 70% der Haarpracht kostet.
Ich glaube, da muss man auch mal klar unterscheiden, wer denn Modularität in seinen Programmen benutzt oder benutzen will. Da sehe ich zum einen Gemeinschaftsprojekte im Internet, wo es wirklich schwer ist, alle auf dem gleichem Stand zu haben (zum Bsp. mit Delphi Version, Benutzten Komponenten etc). Und zum anderen Firmen, die ein oder mehrere Programme haben und sich Module bauen, um Funktionalität auszutauchen. Bei letzterem ist es weniger ein Problem mit den BPLs, da Firmen meist eh Delphi Lizenzen für alle Programmierer kaufen und alle auch mit Komponenten auf dem gleichem Stand sind. Ich selbst habe Jahre in einem grossen Projekt mit mehr als hundert Modulen gearbeitet, 3 Abteilungen waren daran beschäftigt, die ihre Sachen zum Modul-Pool hinzufügten und die andere Abteilungen nutzten. Das ganze natürlich mit Laufzeitpackages. Ich glaub, wir brauchten nur 4 Delphi bpls.

Zitat von Elvis:
Zitat:
Will man allerdings wirklich modular mit Delphi programmieren, muss man mit Laufzeit-Packages arbeiten (also zumindest die Komponenten-BPLs dynamisch linken).
Eben nicht. Wirklich modular ist man, wenn die Module nicht so grauenvoll miteinander verzahnt sind sind. Und das heißt, man ist "wirklich modular" wenn man DLLs benutzt und sich in den exportierten Funktionn auf interoperable Typen wie WideString, Integer, double, Interfaces, OleVariant, etc. beschränkt.
Denn dann explodieren Module nicht stets und ständig, weil irgendein Plugin eine neue Unit nutzt, oder wenn man eine neue Delphiversion nutzen will. Ganz zu schweigen davon, dass man dann Plugins mit anderen Sprachen schreiben kann z.B.: FPC, C++, C#,...
Das was Du willst, sind kleine Funktionsserver in DLLs, wo man mal dies oder jenes berechnet.
Ich sage ganz ehrlich, dass mit Kompatiblität zu anderen Compilern oder Programmiersprachen weniger interessiert. Das, mwas ich mit Delphi nicht machen kann, hat in Modulen eh nichts zu suchen. Und eine clever gebaute Bibliothek vrhindert auch grosse Probleme mit Laufzeitpackages.
So kann man zum Bsp. sein Internetkram (z.b. durch Indy Komponenten) in nur einem Module halten, braucht kein Laufzeitpackage dafür dann und sagt dem Module, was man braucht. Praktizier ich mit Erfolg in meiner Test-Anwendung.

Zitat von Elvis:
Zitat von MyRealName:
Allerdings sah ich auch durch mein Test-Programm, das sich neue Versionen von meinen Komponenten bauen konnte und meist auch ohne die Anwendung oder die DLLs zu kompilieren dann auch weiter nutzen. Man muss halt nur aufpassen, dass man keine published properties löscht Oder Methoden umbenennt.

Allerdings ist zu empfehlen, vorhandene Projekte neu zu übersetzen, wenn man ein neues Package baut
Dann könnte man gleich eine Single-Exe nehmen ohne all die Zeit mit Package-Issues zu verschwenden.
Nein, weil man ja die Packages nicht alle 2 Tage neu übersetzt. Es gibt ja schliesslich einen Stand, da sind die eigenen Komponenten fertig, ab da übersetzt man nicht mehr. Davor ist man insgesamt noch im Entwicklungs-Stadium und da macht es nichts aus, ob man neu übersetzt.
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
679 Beiträge
 
Delphi 10.4 Sydney
 
#24

Re: Plugins: Datenaustausch zwischen DLL und Hauptprogramm

  Alt 27. Nov 2009, 13:58
Zitat von Elvis:
Für non-visuelle macht es mehr Sinn von vorn herein auch innerhalb der Exe auf einer Interface-basierte API aufzubauen.

Zum Beispiel sowas (aus den Fingern gesaugt)
Delphi-Quellcode:
var
  menu : IMenuProvider;
  menuItem : IMenuItem;
begin
  menu := Services.GetService(IMenuProvider) as IMenuProvider;
  menuItem := menu['Edit'].AddItem('Copy');
  menuItem.Caption := '&Copy';
  menuItem.Click := @CopyClickHandler;
end;
Auf die Art hat man genau die Art Dog-Fooding, die nötig ist damit Plugins genügend Möglichkeiten haben um wirklich sinnvoll zu sein. Denn wenn die API, die auch die Plugins nutzen, nicht mächtig genug ist, merkst du das schon während du deine HauptApp schreibst.
Nicht alle mögen diese Art der Programmierung, wie sie schon in der Delphi-IDE genutzt wird. Und wenn man bei einem Rein-Delphi-Programm bleiben will, dann braucht man das auch nicht.
Als ich die MAF Components gebaut habe, wollte ich diese Art der Programmierung extra vermeiden und den Leuten die Möglichkeit geben, ihren gewohnten Delphi-Stil beizubehalten. Bei mir können sich Plugins in Funktionen "reinhängen", neue Funktionen zur Verfügung stellen oder auch vorhandene "umleiten", weil die alten buggy sind oder weil man etwas für einen Kunden ändern musste, der das Standart-Verhalten nicht mochte.

Und anstelle von der obigen Version, wo jedes Plugin sich am Menü selbst anmeldet, gehe ich im Normalfall die anderen Weg herum, wo es nur eine zentrale Stelle gibt, wo Menü-Punkte angemeldet werden, die Plugins liefern sozusagen nur die Daten, mit denen sie angemeldet werden wollen. Das macht es einfacher, etwas zu ändern, da man eben nur eine Stelle hat, wo etwas passiert. So kann man zum Bsp. vom Delphi-Standart TMainMenu auf ein Menu von 3rd-party Komponenten umstellen, weil es vielelicht besser aussieht oder die Funktionen hat, die man braucht für sein Programm.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 3     123   


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 18:11 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