Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Runtime-Packages, visual inheritance, Updaten der Runtime-Packages ohne exe-Update (https://www.delphipraxis.net/171512-runtime-packages-visual-inheritance-updaten-der-runtime-packages-ohne-exe-update.html)

RSE 9. Nov 2012 13:30


Runtime-Packages, visual inheritance, Updaten der Runtime-Packages ohne exe-Update
 
Hallo,

ich arbeite gerade an einem größeren Projekt, bin noch ziemlich am Anfang. Jetzt bin ich gerade auf Runtime-Packages als Alternative zu DLLs gekommen. Konkret hat mich das hier inspiriert:
http://etutorials.org/Programming/ma...side+Packages/
Dort wird gezeigt wie man eine Form aus einem zur Laufzeit dynamisch geladenen Package benutzen kann. Ein Chapter zuvor wird davor gewarnt, dass die exe neu compiliert werden muss, wenn in den Interface-Abschnitten der Units in den Packages etwas verändert wird:
http://etutorials.org/Programming/ma...lphi+Packages/
Ich gehe mal stark davon aus, dass diese Warnung nur auf statisch gelinkte Runtime-Packages zutrifft.

Nun zu meiner eigentlichen Frage: Ich habe vor in meiner exe eine von TForm abgeleitete Basisklasse zu definieren und diese in verschiedenen Packages verschieden zu spezialisieren (mittels visual inheritance). Aus der exe heraus erfolgt der Zugriff ausschließlich auf die Elemente (Methoden, Eigenschaften etc.) der Basisklasse, die exe weiß nichts von der Spezialisierung. Unter diesen Voraussetzungen kann ich doch nun ohne weiteres während der Laufzeit der exe solch ein Package entladen, die Package-Datei updaten, neu laden, die Form wieder instanzieren (über eine Klassenvariable, siehe Quelltextbeispiel unten) und anzeigen.
Delphi-Quellcode:
var
  FormSpez: TForm;
  FormClass: TFormClass;
  HandlePack: HModule;
begin
  // try to load the package
  HandlePack := LoadPackage('PackWithForm.bpl');
  FormClass := TFormClass(GetClass);
  FormSpez := FormClass.Create(Application);
  FormSpez.ShowModal;
  FormSpez.Free;
  UnloadPackage(HandlePack);
Da ich noch an weiteren Stellen erst einmal herausbekommen muss, wie so etwas tatsächlich gemacht werden muss (z.B. Einstellungen in Delphi etc.), möchte ich gerne im Vorfeld hier klären, ob das Vorhaben so machbar ist, oder ob es von vornherein zum Scheitern verurteilt ist. Wenn ich mich damit bereits auskennen würde, würde ich es natürlich selbst mal schnell austesten ;-)


MfG
RSE

Elvis 9. Nov 2012 16:41

AW: Runtime-Packages, visual inheritance, Updaten der Runtime-Packages ohne exe-Updat
 
Eigentlich machen Runtime packages nur für ein Programm Sinn: die Delphi IDE.

Die drakonischen Einschränkungen, die du dir damit aufhalst lohnen sich einfach nicht.
Du musst nämlich
  • gegen die gleiche RTL
  • mit exakt dem gleichen Compiler kompilieren
  • und teuflisch aufpassen, keine Unit namen über all deine Packages doppelt zu haben

Wenn du deine Binaries aufteilen willst, dann kannsu das mit DLLs und Interfaces machen.
Aber in Delphi ist es ziemlich einfach eine große Echse zu erzeugen, egal in wievielen Packages man den Source verteilt hat.
Sollten halt bloß keine Runtime-Packages sein.

Du wirst dich sonst nämich ständig dabei erwischen, komplett alle Packages neu verteilen zu müssen.
Weil du zwar nur ein paar Kleinigkeiten geändert haben magst, aber da ihr auch ein Hotfix (mit RTL Fixes) in eurem Delphi installiert habt, sind alle Packages invalidiert.
Das Argument mit den kleineren Update-Downloads ist IMO nur ein theorethisches.

RSE 9. Nov 2012 17:24

AW: Runtime-Packages, visual inheritance, Updaten der Runtime-Packages ohne exe-Updat
 
@Elvis: Wir benutzen Delphi XE, ich wüsste nicht, was es da für Updates an der RTL geben sollte, vielleicht geht da aber auch was an mir vorbei. Die drakonischen Einschränkungen, die du aufführst, sind mit einer Projektgruppe leicht zu regeln.

Das Programm stellt Callaktionen für ein Callcenter bereit. An der Grundfunktionalität wird sich also äußerst selten etwas ändern. Auch die Callaktionen sind sich sehr ähnlich (die Basisklasse aus meinem ersten Post). Was sich allerdings mehrfach täglich ändern kann, sind die Spezialisierungen - die Callaktionen selbst. Der Vorteil, den ich mir durch die Runtime-Packages verspreche ist der, dass das Programm nicht neu gestartet werden muss, um die Callaktion zu aktualisieren. Die exe kann sogar selbst auf Aktualisierungen prüfen und diese ungefragt aus unserem lokalen Netz downloaden.

Inzwischen habe ich mich natürlich weiter informiert und bin auf ein anderes Problem gestoßen: Die Spezialisierung der Basisklassen geschieht über Visual Form Inheritance (VFI). Das ist aber nur möglich, wenn die Basisklassen in einem eigenen Package sind und statisch geladen werden.
http://www.delphigroups.info/2/12/473336.html

Wenn ich das richtig verstanden habe, gibt es 3 Arten, ein Package einzubinden:
  1. Als Entwurfszeitpackage (wird direkt in die exe gelinkt)
  2. Als statisches Runtimepackage - benötigt bpl zur Runtime + dcp zur Designtime (wird beim Laden der exe gelinkt)
  3. Als dynamisches Runtimepackage - benötigt bpl zur Runtime (ich muss die Library selbst ähnlich wie eine DLL mit LoadPackage einbinden - siehe 1. Post)
Offenbar brauche ich für mein Vorhaben folgende Konstellation:
  • In der exe ist nur Code, der die Callaktionen managt, auf Updates prüft etc.
  • In einem Package "Basis" ist der Code, der die Gemeinsamkeiten aller Callaktionen darstellt (die Basisklassen).
  • Jede Callaktion hat ihr eigenes Package
  • Das Basispackage muss in die exe sowie in jedes Callaktions-Package als statisches Runtime-Package eingebunden werden.
So weiß die exe alles, was sie über die Callaktionen wissen muss (Code aus den Basisklassen) und die Callaktionen können visuell von den Basisklassen abgeleitet werden. Das Instanzieren einer Callaktion erfolgt dann wie im Beispiel im 1. Post.


Aktuell bin ich am Suchen, wie ich Packages als statische Runtimepackages einbinden kann. In der exe scheint das in den Projektoptionen auf der Seite Packages der untere Teil zu sein. Ich weiß allerdings nicht, ob die Checkbox "Laufzeit-Packages verwenden" bewirkt, dass ich alle dort bereits eingetragenen Packages als Laufzeit-Packages mitliefern müsste. Zweites Problem: Der untere Bereich ist bei Packages grau.

Uwe Raabe 9. Nov 2012 22:04

AW: Runtime-Packages, visual inheritance, Updaten der Runtime-Packages ohne exe-Updat
 
Zitat:

Zitat von RSE (Beitrag 1190551)
Ich weiß allerdings nicht, ob die Checkbox "Laufzeit-Packages verwenden" bewirkt, dass ich alle dort bereits eingetragenen Packages als Laufzeit-Packages mitliefern müsste. Zweites Problem: Der untere Bereich ist bei Packages grau.

Wenn du die CheckBox anklickst, kannst du das Feld editieren. Du schreibst da nur die Packages rein, die du als Runtime-Packages mitliefern willst. Dazu kommen noch die, die von den Runtime-Packages required werden (z.B. RTL, VCL).

Die Units aus den Packages, die du dynamisch laden willst, dürfen im Source nicht verwendet werden.

hanspeter 10. Nov 2012 07:33

AW: Runtime-Packages, visual inheritance, Updaten der Runtime-Packages ohne exe-Updat
 
Zusätzlich zu den verwendeten bpl gibt es noch versteckte BPL Abhängigkeiten. Das führt dazu, dass ein Delphiprogramm noch eine Reihe bpl beim Start verlangt,
die im Programm selbst garnicht verwendet werden.
In meinem Projekt waren das so um die 70 bis 80 bpl, die zusätzlich mitgeliefert werden mussten.
Fehlende oder geänderte bpl merkt man erst beim Kunden, da hier erst die isolierte Umgebung vorhanden ist.
Also vor der Auslieferung in einer delphifreien VM testen, ob das Programm startet.
Dann beten, das kein weiteres Delphiprogramm auf dem gleichen Rechner bpl benötigt. Das muss nicht mal mit unterschiedlichen Delphi-Versionen compiliert sein.
Das bpl Konzept ist antiquiert und verursacht nur Ärger.
Wenn wirklich Modular, dann entweder dll und Interface oder Com-Technologie.
Eine große Exe und Schluss oder eine kleine Exe und 80 bis 90 bpl die versioniert überwacht und updatet werden müssen, was ist besser?
Ich habe runtime bpl zwischenzeitlich aus allen Projekten wieder herausgeworfen, da Nutzen und zusätzlicher Aufwand in keinem Verhältnis stehen.

Gruß
Peter

Uwe Raabe 10. Nov 2012 10:04

AW: Runtime-Packages, visual inheritance, Updaten der Runtime-Packages ohne exe-Updat
 
Zitat:

Zitat von hanspeter (Beitrag 1190575)
Zusätzlich zu den verwendeten bpl gibt es noch versteckte BPL Abhängigkeiten. Das führt dazu, dass ein Delphiprogramm noch eine Reihe bpl beim Start verlangt,
die im Programm selbst garnicht verwendet werden.

..zumindest nicht direkt.

Zitat:

Zitat von hanspeter (Beitrag 1190575)
In meinem Projekt waren das so um die 70 bis 80 bpl, die zusätzlich mitgeliefert werden mussten.
Fehlende oder geänderte bpl merkt man erst beim Kunden, da hier erst die isolierte Umgebung vorhanden ist.
Also vor der Auslieferung in einer delphifreien VM testen, ob das Programm startet.

Oder man schaut nach dem Compilieren mal unter Projekt - Info auf die Liste "Verwendete Packages".


Zitat:

Zitat von hanspeter (Beitrag 1190575)
Dann beten, das kein weiteres Delphiprogramm auf dem gleichen Rechner bpl benötigt. Das muss nicht mal mit unterschiedlichen Delphi-Versionen compiliert sein.

Grundsätzlich sollten BPLs, die mit unterschiedlichen Delphi-Versionen compiliert sind, auch unterschiedliche Namen haben. Ansonsten könnte man ja auch nicht verschiedene Delphi-Versionen gleichzeitig auf dem Rechner haben. Wer es dann ganz ordentlich machen will, gibt der BPL dann auch noch die eigene Versionsnnummer im Dateinamen mit. Bei neueren Delphi-Versionen helfen da die Einträge für LIB-Suffix und LIB-Version. Im Zweifelsfall packt man die benötigten Packages in das Verzeichnis, wo auch die EXE liegt.


Zitat:

Zitat von hanspeter (Beitrag 1190575)
Das bpl Konzept ist antiquiert und verursacht nur Ärger.
Wenn wirklich Modular, dann entweder dll und Interface oder Com-Technologie.

DLLs sind sicher nicht besser als BPLs was unterschiedliche Versionen auf dem Rechner betrifft. Und COM unter OSX könnte auch etwas haarig werden. Delphi-Packages funktionieren aber unter allen Zielplattformen. Antiquiert im Sinne von "gibt es schon sehr lange" - ja, aber immerhin nutzt .NET dieses Konzept ja ziemlich intensiv.

Zitat:

Zitat von hanspeter (Beitrag 1190575)
Eine große Exe und Schluss oder eine kleine Exe und 80 bis 90 bpl die versioniert überwacht und updatet werden müssen, was ist besser?
Ich habe runtime bpl zwischenzeitlich aus allen Projekten wieder herausgeworfen, da Nutzen und zusätzlicher Aufwand in keinem Verhältnis stehen.

Wie jede Technologie muss man wissen was man tut und Aufwand und Nutzen gegeneinander abwägen. Es ist sicher kein brauchbarer Weg um die EXE-Größe zu verkleinern oder den Update-Aufwand zu minimieren. Wenn es aber wie in diesem Fall um visual inheritance geht, sind dynamische Packages ein durchaus gangbarerer Weg. Mit anderen Ansätzen wird die Lösung sicher nicht leichter.

Es gibt übrigens noch ein anderes Beispiel, wo das Package-Konzept erfolgreich für einen modularen, dynamischen Aufbau verwendet wird: FinalBuilder!

RSE 10. Nov 2012 12:25

AW: Runtime-Packages, visual inheritance, Updaten der Runtime-Packages ohne exe-Updat
 
Vielen Dank für das Aufweisen der Stolperfallen. Mein Ziel ist es nicht, die Größe des Gesamtprogramms zu verringern, sondern zu modularisieren und Module zur Programmlaufzeit updaten zu können.

Habe ich denn die 3 verschiedenen Arten, Packages einzubinden, oben korrekt wiedergegeben?

Wieso kann ich ein Package nicht statisch in ein anderes linken?

Würden sich die vielen (80-90???) benötigten BPLs nicht als Designtime-Packages einbinden lassen (so wie in eine "normale" exe)?

sx2008 10. Nov 2012 12:49

AW: Runtime-Packages, visual inheritance, Updaten der Runtime-Packages ohne exe-Updat
 
Zitat:

Zitat von RSE (Beitrag 1190551)
Wenn ich das richtig verstanden habe, gibt es 3 Arten, ein Package einzubinden:
  1. Als Entwurfszeitpackage (wird direkt in die exe gelinkt)
  2. Als statisches Runtimepackage - benötigt bpl zur Runtime + dcp zur Designtime (wird beim Laden der exe gelinkt)
  3. Als dynamisches Runtimepackage - benötigt bpl zur Runtime (ich muss die Library selbst ähnlich wie eine DLL mit LoadPackage einbinden - siehe 1. Post)

Da hast du etwas falsch verstanden.
Design-Time-Packages werden ausschlieslich von der Delphi-IDE geladen und benützt.
Sehr häufig benützt das Design-Time-Package ein Runtime-Package damit Komponenten innerhalb der IDE "leben" können.
Es gibt aber auch Design-Time-Packages, die ganz ohne Runtime-Packages daherkommen.
Sie enthalten sog. "Experten" also Erweiterungen der Delphi-IDE.

Nur Runtime-Packages können später in Anwendungen benützt werden.

Uwe Raabe 10. Nov 2012 14:24

AW: Runtime-Packages, visual inheritance, Updaten der Runtime-Packages ohne exe-Updat
 
Zitat:

Zitat von sx2008 (Beitrag 1190603)
Nur Runtime-Packages können später in Anwendungen benützt werden.

Und Runtime-Packages können sowohl statisch als auch dynamisch gelinkt werden. Sobald eine Unit eines Runtime-Packages direkt im Quellcode referenziert wird, muss das Package statisch gelinkt werden (heißt, es wird beim Programmstart geladen). Die Units eines dynamischen Package sind beim Compilieren der Exe nicht bekannt.

RSE 10. Nov 2012 18:49

AW: Runtime-Packages, visual inheritance, Updaten der Runtime-Packages ohne exe-Updat
 
OK, das mit den Packages hab ich jetzt verstanden. Die wichtigste Frage bleibt aber offen. Wie ich oben verlinkt habe, kann ich nur visuell von einer Form ableiten, wenn die Basisklasse im gleichen Modul definiert ist oder statisch ins Modul gelinkt wird. Die Compiler-Option des statischen Linkens ist aber bei Packages deaktiviert. Kann ich also in Packages grundsätzlich keine visuelle Ableitung von einer außerhalb des Packages definierten Klasse vornehmen? Damit würde mein ganzer Ansatz nicht mehr aufgehen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:33 Uhr.
Seite 1 von 2  1 2      

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