![]() |
Units in bpl auslagern und als Package in Exe/Dll einbinden
Hallo zusammen,
ich bin gerade dabei, ein größeres Projekt in kleinere Teile aufzuteilen. Dabei habe ich einzelne Module in dll-Dateien gepackt und binde diese dynamisch ein. Um die Dateigrößen - auch der Module - kleiner zu halten, habe ich begonnen, mit Runtime-Packages zu kompilieren. Damit ist jetzt jedes Modul (mit Formular) nur noch 1-2 MB groß, obwohl verschiedene Dritt-Komponenten eingebunden sind (z.B. DevExpress, UniDAC...). Soweit funktioniert es ganz gut. Nun suchte ich noch nach weiteren größeren Units, die ich überall verwende und daher auch gerne auslagern würde. Dabei bin ich z.B. auf die Unit SuperObject gestoßen, die ich für die Json-Verarbeitung sehr praktisch finde. Wenn ich diese einbinde, wird meine Exe (oder die dll) auch gleich um über ein MB größer. Das würde sich also lohnen, sie auch in eine bpl-Datei auszulagern. Aber hier bin ich ratlos. Wie geht das? Geht das überhaupt? Oder kann ich nur Komponenten auslagern? Aber für die rtl gibt es doch auch die rtl290.bpl. Auf der Suche nach einer rtl290.dpk bin ich auch nicht fündig geworden. Hat mir jemand einen Tipp? Oder geht das gar nicht so, wie ich mir das vorstelle? Wie könnte man gemeinsam verwendeten Code aus solchen Units (auch mehrere meiner eigenen Utility-Units wären dafür Kandidaten) einmal kompilieren, dann überall einbinden und damit die Dateien insgesamt kleiner halten? Vielen Dank für Euer Mitdenken und Eure Erfahrungen Harald |
AW: Units in bpl auslagern und als Package in Exe/Dll einbinden
Überleg Dir das gut. Man landet dann ganz schnell in der DLL/BPL(-Abhängigkeiten)-Hölle.
Heutzutage sind große Programmdateien wirklich kein Problem mehr. |
AW: Units in bpl auslagern und als Package in Exe/Dll einbinden
Wenn es wirklich ein Größenproblem ist, muss man genau prüfen, ob das Ganze damit nicht schlimmer wird. In der Regel ist die Größe aller BPLs plus der EXE bei Verwendung von Packages größer als die EXE wenn sie ohne Packages compiliert wird. Nur im letzten Fall kann der Linker allen nicht benötigten Code eliminieren. Packages enthalten immer den kompletten Code, da man ja nicht weiß, ob er später benötigt wird oder nicht. Nur bei eine sehr hoher Wiederverwendung der Packages von mehreren EXEs kann sich das dann rechnen.
Beispiel: Eine neue VCL-Forms Anwendung mit nicht mehr als einem leeren Form ohne weiteren Code erzeugt eine EXE von 2.417.392 Byte unter Delphi 12.1, die sich bei Compilieren mit Packages auf 188.928 Byte reduziert. Allerdings muss man dann die rtl290.bpl mit 12.734.440 Byte und die vcl290.bpl mit 4.419.048 Byte mitliefern. Dazu kommen noch die Sprachdateien rtl290.de und vcl290.de mit 136.680 Byte respektive 329.200 Byte. Das macht insgesamt 17.808.286 Byte - mehr als 7x so viel wie die ursprüngliche EXE hat. Und das sind nur zwei BPLs, die da verwendet werden. |
AW: Units in bpl auslagern und als Package in Exe/Dll einbinden
Hmmm, ja, über diese Abhänigkeiten habe ich schon länger gegrübelt. Da es sich um ein relativ einfaches Rahmenprogramm mit aktuell ca. 15 eingebundenen Dll-Modulen und in Zukunft wohl noch ein paar Duzend dazukommen werden, schien mir dieser Weg mit den bpl-Abhänigkeiten geeignet. So muss ich nicht bei jedem neuen Modul alles wieder (mit zig MB) neu ausliefern - und könnte auch neue Funktionen/Module an einzelne User ausliefern, ohne die anderen mit einem riesigen Update zu belasten...
Naja, dass das mit den bpl-Dateien nicht ganz einfach ist und manche (neue) Probleme schafft, habe ich schon erfahren. Aber wenn ich das Ganze modular erweiterbar machen möchte, fiehl mir keine bessere Lösung ein. Denn ich will ja nicht mit jeder neuen dll-Datei wieder 20-30 MB ausliefern. Das wäre auch insgesamt mit einigen Dutzend Modulen zu riesig. Deshalb doch meine Frage: Ist das möglich - und wie? - eine eigene oder fremde Unit in eine bpl zu verpacken, ohne daraus eine Komponente machen zu müssen und diese dann zu registrieren? Kann ich einfach nur die Unit in eine bpl packen und dann auf den Code zugreifen? Und wie ginge das dann? Oder geht das nur, indem ich z.B. wie in einer dll eine Funktion, z.B.
Delphi-Quellcode:
exportiere und diese dann einbinde. Das hieße ja dann, ich müsste in jedem meiner Dll-Module Code einbauen zum dynamischen Laden der Dll und ihrer Funktionen. Oder ich schreibe eine Unit, die alle dll-Funktionen importiert und binde diese dann statisch ein...
SuperObject.SO()
Ich verstehe die Interna leider nicht gut - aber es schien mir doch charmant, ähnlich wie bei der rtl290.bpl einfach nur eine bpl-Datei einzubinden (in den Projekt-Optionen) und dann alle Funktionen des Interfaces einer Unit verfügbar zu haben. Viele Grüße Harald |
AW: Units in bpl auslagern und als Package in Exe/Dll einbinden
Zitat:
Das lohnt sich nur zur Befriedigung eines Perfektionsbedürnisses (kenne ich nur zu gut). Finanziell lohnt sich das ganz sicher nicht. Selbst beim Aspekt CO2 habe ich starke Zweifel. |
AW: Units in bpl auslagern und als Package in Exe/Dll einbinden
Zitat:
Ich schließe mich da auch meinen Vorrednern an: Deine Intention ist vermutlich fehlgeleitet. Wenn du keine besseren Argumente hast als die bisher vorgetragenen, würde ich von dem Vorhaben abraten. Viele von uns waren in der Vergangenheit sicher auch schon an dem Punkt (mich eingeschlossen) und haben es am Ende dann doch wieder fallen gelassen. Es gibt sicher Anwendungen, die von Packages profitieren oder anders gar nicht realisierbar wären. Deine Anwendung gehört offenbar nicht dazu. |
AW: Units in bpl auslagern und als Package in Exe/Dll einbinden
Und Du müsstest extrem viel auf die Kompatibilität achten oder halt immer irgendwas nachladen oder mit in den Installer packen, so wie es immer noch Programme gibt, die irgendeine bestimmter C-- Runtimeversion aus 2013 o.ä. verlangen und installieren..... :-(
|
AW: Units in bpl auslagern und als Package in Exe/Dll einbinden
Noch anders formuliert: Wenn Du nicht gerade auf Disketten auslieferst, hast Du durch eine Auslagerung in BPL oder DLL nichts gewonnen außer Bauchschmerzen. Und selbst dann, konnte man schon vor 30 Jahren Zip auf mehrere Disketten aufteilen lassen (disk spanning seit V2.0 von 1993 des ZIP Formats).
|
AW: Units in bpl auslagern und als Package in Exe/Dll einbinden
Also wenn die Größe für Updates der einzige Grund ist. Dem kann geholfen werden.
In einigen Gebieten (Inland/Ausland) gibt es langsame Internetverbindung. Daher ist das ein Thema für uns. Lösung: Binäre Delta Updates. D.h. eine Komprimierte Übertragung von Änderungen. Etwas teuer aber gut wäre z.B. RTPatch von Pocketsoft. Patch Management kosten zwar etwas, man muss aber nichts an der Entwicklung ändern, nur um Platz für Updates einzusparen. |
AW: Units in bpl auslagern und als Package in Exe/Dll einbinden
Und vergiss nicht, dass du dann auch schnell noch weitere Packages mitgeben mußt.
z.B. RTL, VCL uvm. in der RTL liegen z.B. die System.pas (Speichermanagement/Strings), SysUtils usw. C:\Program Files (x86)\Embarcadero\Studio\22.0\Redist\win32 |
AW: Units in bpl auslagern und als Package in Exe/Dll einbinden
Nur, um sicherzustellen, dass ich das richtig verstehe: Es geht um ein relativ einfaches Rahmenprogramm, welches Funktionalität mittels verschiedener Plugins als DLL anbietet? Und dieses System existiert so bereits?
Solange da die DLLs sich nicht gegenseitig aufrufen sondern nur ein vorgegebenes (prozedurales?) Interface für das Hauptprogramm zur Verfügung stellen, kann Dein Vorhaben durchaus sinnvoll sein, denn es spart für jede DLL alles das, was in den Standard-Packages zur Verfügung steht. Auch das Hauptprogramm kann dadurch kleiner werden. Aber ich würde es bei den Standard-Packages für RTL und VCL, plus evtl. von wenigen Fremdkomponenten belassen. Sobald Du anfängst, eigenen Code in Packages zu verlagern, wird es komplex und lohnt in der Regel auch nicht. Wichtig ist eine feste, dokumentierte Schnittstelle und eine Versionierung der DLLs, aber das sollte es für ein solches Programm bereits sowieso geben, unabhängig davon, ob Packages verwendet werden oder nicht. |
AW: Units in bpl auslagern und als Package in Exe/Dll einbinden
Nja, grundsätzlich spricht nichts dagegen, Packages anstatt DLLs zu verwenden.
Dynamisch laden lassen auch sie sich ![]() ![]() ![]() ![]() ![]() ![]() und zusätzlich hat man den Vorteil erstmal ohne ShareMem rumzuspielen und auch stärker gemeinsamten Code, Klassen, usw. verwenden zu können. OK, "DLLs" aus fremden Programmiersprachen fallen dann außen vor. Und bei RuntimePackages muß man unbedingt aufpassen, dass die EXE, DLLs und BPLs in der selben Delphi-Version, Unterversion und selten sogar mit dem selben Patch kompiliert sein müssen. Hier bietet es sich inzwischen an, mit dem automatischen Suffix zu arbeiten. (LibSuffix AUTO, siehe Projektoptionen > Beschreibung) ![]() Alternativ kann man natürlich auch klassisch mit COM-Interfaces arbeiten, sowie ganz einfache "Funktionen" in DLLs aufrufen, oder Dergleichen. Ja, praktisch ist es also auch möglich Erweiterungen in der Delphi-IDE zu nutzen, ohne dass beim (de)installieren die IDE beendet und neu gestartet werden muß. :freak: |
AW: Units in bpl auslagern und als Package in Exe/Dll einbinden
TMSSoftware bietet dazu auch etwas an:
![]() Ob das allerdings passend sein könnte, kann ich nicht beurteilen. |
AW: Units in bpl auslagern und als Package in Exe/Dll einbinden
Habe jetzt mal versucht nach Eurem Rat, die Module und das Hauptprogramm ohne Packages zu kompilieren. Leider klappt das, vermutlich wegen der verwendeten Komponenten, gar nicht. Ich denke, wenn ich mich recht erinnere, dass das an dem verwendeten TdxBarManager von DevExpress liegt. Muss ich aber noch testen.
Es gibt einen Toolbar im Hauptprogramm und dann jeweils auch wieder welche in den einzelnen Modulen, die als dll eingebunden werden und dort in einem Panel das jeweilige Modulfenster anzeigen. Ich glaube, mehrere BarManager vertragen sich nicht. Wie gesagt, muss ich noch testen, aber aktuell wird das Modul-Formular nicht im Panel angezeigt - und es erscheint eine leider kryptische Fehlermeldung. Ich geb Bescheid, woran es wirklich liegt, wenn ich die Zeit habe, das in Ruhe zu testen. Ich bin übrigens gerade dran, eine Wiki-Seite für das Programm zu erstellen. Hier mal die url, auch wenn es noch lange nicht "fertig" ist. So kann man sich schon ein wenig vorstellen, wie das Programm aussieht und was es tut :-) ![]() Viele Grüße Harald |
AW: Units in bpl auslagern und als Package in Exe/Dll einbinden
Objekte/Klassen dürften NIEMALS über DLL-Grenzen hinweg genutzt werden. (ohne Packages)
ohne ShareMem hat jeder seinen eigenen Speichermanager * in einem Modul (EXE/DLL) reservierter Speicher kann nicht in einem anderen Modul verändert werden * * die Reservierung des Speichers ... der Inhalt ist was Anderes * * z.B. die Länge eines Strings ändern, bzw. den String einer anderen Variable/Parameter zuweisen (wenn es passieren kann, dass ein String dabei freigegeben wird) ohne Packages hat jedes Modul seine eigene Deklaration von Typen und ihrer Methoden, sowie eine komplett eigene TypeInfo/RTTI * selbst wenn man denkt es sei identisch, ist das NIEMALs sicher * durch Optimierung kann der Kompiler/Linker optimieren und z.B. "ungenutzte" Felder in der Klasse "weglassen" * ist das in beiden Modulen unterschiedlich, dann denkst das eine Modul an Adresse+5 wäre das Feld, aber das Andere Modul denkt dort wäre etwas Anderes Bei Nutzung von Interfaces sieht das Anders aus. * hier muß man zwar drauf achten, dass alle Seiten die selbe gleiche Definition besitzen, * aber intern wird jeder Methodenaufruf an das Modul weitergeleitet, wo das Interface/Object erstellt wurde (Create) |
AW: Units in bpl auslagern und als Package in Exe/Dll einbinden
Auch wenn es vielleicht Off Topic erscheint, aber nur zum Verständnis gefragt:
Wenn ich das richtig verstehe ist die Planung, dass die Kunden, je nach Lizenz, nur einige oder alle .dll Dateien zum Hauptprogramm bekommen? Was für ein Prüf Protokoll willst du dafür erstellen? Ich weiss zwar nicht, wie das bei kaufmännischer Software ist, aber bei uns im Steuerungsbereich müsste man alle möglichen Kombinationen an Hauptprogramm und .dll bei jeder Änderung auf Seiteneffekte, Kompatibilität, Eingriffsmöglichkeiten, etc. prüfen. Durch die EU Cyber Richtlinie, die ja jetzt unter anderem auch für Fahrstuhlsteuerungen, Maschinensteuerungen und Fahrzeugsteuerungen gilt, ist das ein erheblicher Test- und Dokumentationsaufwand. Das ist unheimlich Kostenintensiv. Daher machen die meisten im Steuerungsbereich die Einschränkungen über Funktionsfreischaltung im Lizenzcode oder Lizenzdongle und Updates über Binäre Delta Updates. Ist das bei kaufmännischer Software nicht so relementiert? Kann man da wirklich "machen was man will, hauptsache es funktioniert"? Wie macht Ihr da das Qualitätsmanagement und die Prüfdokumentation oder ist das auch nicht notwendig? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:41 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