Verwendung des schwachen Packens
Nach oben zu Packages compilieren
Schwache Units (schwach gepackte Units) sind Units, die in einem Package (d. h., einem Package-Projekt) definiert sind. Bei dynamisch gelinkten Packages erfolgt die Einbindung jedoch anders.
Normalerweise befindet sich eine Unit im Package selbst. Das Linken mit der BPI-Datei (Package-Importbibliothek) führt zu einem Verweis auf das Package.
Im Gegensatz dazu befindet sich eine schwach gepackte Unit in der BPI. Das bedeutet, dass selbst bei einem dynamisch gelinkten Package eine schwach gepackte Unit direkt mit dem Package-Verwendermodul gelinkt wird. Wichtig ist Folgendes: Wenn die BPL-Datei getrennt von der Neucompilierung der Software, die die BPL verwendet, aktualisiert wird, wird die vermeintlich in der BPL enthaltene schwach gepackte Unit in der Software, die sie verwendet, nicht aktualisiert, da sie sich in Wirklichkeit in der Importbibliothek (BPI) befindet und somit in den Package-Verwender eingebunden ist.
Wenn Sie nur eine schwache Unit eines Package verwenden, hängt Ihre Anwendung nicht von diesem Package ab (d. h., Sie haben keine Abhängigkeit von der BPL-Datei). Da die BPI anstelle eines Importobjekts die Objektdatei der Unit enthält (als wäre sie ein statisches Package) und die Objektdatei eingebunden ist, besteht keine Abhängigkeit vom Package selbst. Mit anderen Worten: Schwach gelinkte Units bilden eine Mischung aus dynamisch und statisch, wobei die schwachen Units statisch sind.
Unten finden Sie einige Beispiele, die dieses Verhalten für Delphi und C++Builder beschreiben.
Delphi
Die Direktive $WEAKPACKAGEUNIT
beeinflusst die Art und Weise, in der eine .dcu
-Datei in den .dcp
- und .bpl
-Dateien eines Package gespeichert wird.
Die Direktive {$WEAKPACKAGEUNIT ON}
in einer Unit-Datei veranlasst den Compiler, diese Unit, wenn möglich, nicht in BPLs einzubinden. Er erzeugt stattdessen eine nicht an das Package gebundene lokale Kopie der Unit, wenn diese von einer anderen Anwendung oder einem anderen Package benötigt wird. Eine solche Unit wird als schwach gepackt bezeichnet.
Angenommen, Sie haben ein Package mit dem Namen "pack1" erzeugt, das als einzige Unit "unit1" enthält. "unit1" verwendet keine weiteren Units, ruft aber "rare.dll" auf. Wenn unit1.pas (Delphi) oder unit1.cpp (C++) die Direktive {$WEAKPACKAGEUNIT ON}
enthält und Sie das Package compilieren, wird "unit1" nicht in pack1.bpl eingebunden, und Sie brauchen zusammen mit "pack1" keine Kopien von "rare.dll" weiterzugeben. "unit1" wird jedoch nach wie vor in pack1.dcp eingebunden. Wenn "unit1" von anderen Packages oder Anwendungen referenziert wird, die ""unit1"" verwenden, wird sie aus pack1.dcp kopiert und direkt in das Projekt compiliert.
Angenommen, Sie fügen dem Package "pack1" eine zweite Unit namens "unit2" hinzu. "unit2" verwendet "unit1". In diesem Fall wird "unit1" selbst dann in pack1.dcp eingebunden, wenn unit1.pas beim Compilieren von "pack1" die Direktive {$WEAKPACKAGEUNIT ON}
enthält. Andere Packages oder Anwendungen, die "unit1" referenzieren, verwenden dagegen die nicht in ein Package eingebundene Kopie aus der Datei pack1.dcp.
{$WEAKPACKAGEUNIT ON}
dürfen keine globalen Variablen und Abschnitte zur Initialisierung und Finalisierung enthalten.Mit der Direktive {$WEAKPACKAGEUNIT ON}
stehen Entwicklern, die ihre Packages für andere Programmierer bereitstellen möchten, umfangreiche Möglichkeiten zur Verfügung. So wird beispielsweise die Weitergabe selten verwendeter DLLs überflüssig, und Konflikte zwischen Packages, die von derselben externen Bibliothek abhängig sind, lassen sich leichter vermeiden.
Die Unit "PenWin" referenziert beispielsweise die Datei PenWin.dll. Diese Unit wird von den wenigsten Projekten verwendet, und auf den wenigsten Computern ist PenWin.dll installiert. Aus diesem Grund ist die Unit "PenWin" in "vcl" nur schwach gepackt. Beim Compilieren eines Projekts, das die Unit "PenWin" und das Package "vcl" referenziert, wird "PenWin" aus der Datei vcl70.dcp kopiert und direkt in das Projekt eingebunden. Die resultierende ausführbare Datei ist statisch mit PenWin.dll verknüpft.
Wäre "PenWin" nicht schwach gepackt, würden sich zwei grundsätzliche Probleme ergeben. Erstens würde "vcl" selbst statisch zu PenWin.dll gelinkt, was zur Folge hätte, dass "vcl" auf Computern, auf denen PenWin.dll nicht installiert ist, nicht mehr geladen werden könnte. Zweitens würde der Compiler den Versuch zurückweisen, ein Package zu erzeugen, das "PenWin" enthält, da die Unit "PenWin" sowohl in "vcl" als auch in Ihrem eigenen Package enthalten wäre. Ohne schwaches Packen könnte "PenWin" also nicht so einfach mit Standardversionen von "vcl" weitergegeben werden.
C++Builder
Die Direktive #pragma package(smart_init, weak)
beeinflusst die Art und Weise, wie eine .obj-Datei in .bpi- und .bpl-Dateien eines Packages gespeichert wird. (Detaillierte Informationen über die vom Compiler und Linker erzeugten Dateien finden Sie unter Packages und Standard-DLLs.) Wenn #pragma package(smart_init, weak)
in einer Unit-Datei enthalten ist, lässt der Linker, wenn möglich, die Unit aus BPLs weg. Wenn die Unit für eine andere Anwendung oder ein anderes Package erforderlich ist, legt der Linker eine lokale Kopie der Unit (ohne Package) an. Eine solche Unit wird als "schwach gepackt" bezeichnet.
Angenommen, Sie haben ein Package mit dem Namen PACK erzeugt, das als einzige Unit "UNIT1" enthält. UNIT1 verwendet keine weiteren Units, ruft aber RARE.dll auf. Wenn Sie #pragma package(smart_init, weak)
in UNIT1.cpp einfügen, wird UNIT1 beim Erzeugen Ihres Package nicht in PACK.bpl einbezogen; Sie müssen keine Kopien von RARE.dll mit PACK weitergeben. Dagegen ist UNIT1 weiterhin in PACK.bpi enthalten. Wenn andere Packages oder Anwendungen, die PACK verwenden, UNIT1 referenzieren, wird sie aus PACK.bpi kopiert und direkt in das Projekt gelinkt.
Angenommen, Sie fügen dem Package "pack1" eine zweite Unit namens "unit2" hinzu. "unit2" verwendet "unit1". In diesem Fall schließt der Linker "unit1" in pack.bpl ein, auch wenn Sie "pack" mit #pragma package(smart_init, weak)
in unit1.cpp compilieren. Aber andere Packages oder Anwendungen, die "unit1" referenzieren, verwenden die Kopie (nicht gepackt) aus pack.bpi.
#pragma package(smart_init, weak)
dürfen keine globalen Variablen enthalten.Mit der Direktive #pragma package(smart_init, weak)
stehen Entwicklern, die ihre Packages für andere C++Builder-Programmierern bereitstellen möchten, umfangreiche Möglichkeiten zur Verfügung. So wird beispielsweise die Weitergabe selten verwendeter DLLs überflüssig, und Konflikte zwischen Packages, die von derselben externen Bibliothek abhängig sind, lassen sich leichter vermeiden.
Die Unit "PenWin" referenziert beispielsweise die Datei PenWin.dll. Diese Unit wird von den wenigsten Projekten verwendet, und auf den wenigsten Computern ist PenWin.dll installiert. Aus diesem Grund ist die Unit "PenWin" in "vcl" nur schwach gepackt. Beim Linken eines Projekts, das die Unit "PenWin" und das Package "vcl" referenziert, wird "PenWin" aus der Datei vcl60.bpi kopiert und direkt in das Projekt eingebunden. Die resultierende ausführbare Datei ist statisch mit PenWin.dll verknüpft.
Wäre "PenWin" nicht schwach gepackt, würden sich zwei grundsätzliche Probleme ergeben. Erstens würde "vcl" selbst statisch zu PenWin.dll gelinkt, was zur Folge hätte, dass "vcl" auf Computern, auf denen PenWin.dll nicht installiert ist, nicht mehr geladen werden könnte. Zweitens würde ein Build-Fehler auftreten, wenn Sie versuchen, ein Package zu erzeugen, das "PenWin" enthält, da die Unit "PenWin" sowohl in "vcl" als auch in Ihrem eigenen Package enthalten wäre. Ohne schwaches Packen könnte "PenWin" also nicht so einfach mit Standardversionen von "vcl" weitergegeben werden.
Weitere Informationen finden Sie in der C++-Dokumentation zu #pragma package(smart_init, weak), in der Delphi-Dokumentation unter Schwach Packen und bei der Direktive für das schwache Packen.