Packages (Delphi)

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Bibliotheken und Packages - Index


Mit Packages werden normalerweise Elemente (außer einfache Prozeduren und Funktionen) exportiert. Bibliotheken sollten nur verwendet werden, wenn eine Interoperabilität mit anderen Programmen erforderlich ist.

Die folgenden Abschnitte enthalten Informationen zum Erstellen und Compilieren von Packages.

  • Package-Deklarationen und Quelltextdateien
  • Packages benennen
  • Die requires-Klausel
  • Zirkuläre Bezüge bei Packages vermeiden
  • Doppelte Package-Referenzen
  • Die contains-Klausel
  • Redundante Verwendung von Quelltext vermeiden
  • Packages compilieren
  • Generierte Dateien
  • Spezielle Compiler-Direktiven für Packages
  • Package-spezifische Befehlszeilenoptionen

Allgemeines zu Packages

Ein Package ist eine auf spezielle Weise compilierte Bibliothek, die von Anwendungen oder der IDE (oder beiden) verwendet wird. Packages ermöglichen eine Neuanordnung des Programmcodes ohne Auswirkungen auf den zugrunde liegenden Quelltext. Dieser Vorgang wird auch als Partitionierung von Anwendungen bezeichnet.

Laufzeit-Packages stellen die Funktionalität bereit, die dem Benutzer die Ausführung einer Anwendung ermöglicht. Entwurfszeit-Packages dienen der Installation von Komponenten in der IDE und der Erstellung von speziellen Eigenschaftseditoren für benutzerdefinierte Komponenten. Jedes Package kann sowohl zur Entwurfszeit als auch zur Laufzeit verwendet werden. Entwurfszeit-Packages referenzieren häufig Laufzeit-Packages in ihren requires-Klauseln.

In Win32 haben Package-Dateien die Namenserweiterung .bpl (Borland Package Library).

Normalerweise werden Packages beim Start einer Anwendung statisch geladen. Mithilfe der Routinen LoadPackage und UnloadPackage (in der Unit SysUtils) können Sie Packages aber auch dynamisch laden.

Hinweis: Wenn eine Anwendung Packages verwendet, muss der Name jeder dort eingebundenen Unit weiterhin in der uses-Klausel jeder Quelltextdatei angegeben werden, von der die Unit referenziert wird.

Package-Deklarationen und Quelltextdateien

Um eine Verwechslung mit anderen Dateien zu vermeiden, die Delphi-Code enthalten, wird jedes Package in einer separaten Quelltextdatei mit der Namenserweiterung .dpk gespeichert. Eine Package-Quelltextdatei enthält keinerlei Typ-, Daten-, Prozedur- oder Funktionsdeklarationen. Sie hat stattdessen folgenden Inhalt:

  • Einen Namen für das Package.
  • Eine Liste weiterer Packages, die von dem neuen Package benötigt werden. Das neue Package wird zu diesen Packages gelinkt.
  • Eine Liste der Unit-Dateien, die das compilierte Package enthält. Das Package stellt im Grunde eine Hülle für diese Quelltext-Units dar, die die Funktionalität des compilierten Package bereitstellen.

Eine Package-Deklaration hat folgende Form:

package PackageName;

  requiresKlausel;

  containsKlausel;

end.

PackageName ist ein gültiger Bezeichner. Die Angabe von requiresKlausel und containsKlausel ist optional. Im folgenden Beispiel wird das Package DATAX deklariert:

 package DATAX;
   requires
   rtl,
   contains Db, DBLocal, DBXpress, ... ;
 end.

Die requires-Klausel enthält weitere externe Packages, die vom deklarierten Package verwendet werden. Die Klausel setzt sich aus der Direktive requires, einer Liste mit Package-Namen, die durch Kommas voneinander getrennt sind, und einem Strichpunkt zusammen. Wenn ein Package keine weiteren Packages referenziert, ist keine requires-Klausel erforderlich.

In der contains-Klausel sind die Unit-Dateien aufgeführt, die compiliert und in das Package eingebunden werden. Die Klausel setzt sich aus der Direktive contains, einer Liste mit Unit-Namen, die durch Kommas voneinander getrennt sind, und einem Strichpunkt zusammen. Auf einen Unit-Namen können das reservierte Wort in und der Name einer Quelltextdatei mit oder ohne Pfadangabe in halben Anführungszeichen folgen. Verzeichnispfade können absolut oder relativ sein. Zum Beispiel:

 contains MyUnit in 'C:\MyProject\MyUnit.pas';

Hinweis: Auf Thread-Variablen (Variablen, die mit threadvar deklariert wurden) in einer Package-Unit können Clients, die dieses Package verwenden, nicht zugreifen.

Packages benennen

Beim Compilieren eines Package werden mehrere Dateien erzeugt. Die Quelldatei für das Package DATAX ist beispielsweise DATAX.DPK. Der Compiler erzeugt daraus eine ausführbare Datei und ein binäres Abbild mit folgenden Namen:

DATAX.BPL und DATAX.DCP

Über den Namen DATAX wird das Package in der requires-Klausel anderer Packages referenziert oder in einer Anwendung verwendet. Package-Namen müssen innerhalb eines Projekts eindeutig sein.

Die requires-Klausel

Die requires-Klausel enthält andere externe Packages, die vom aktuellen Package verwendet werden. Diese Klausel funktioniert wie die uses-Klausel in einer Unit. Ein externes Package, das in der requires-Klausel enthalten ist, wird beim Compilieren automatisch zu jeder Anwendung gelinkt, die sowohl das neue Package als auch eine der Units verwendet, die im externen Package enthalten sind.

Wenn die Unit-Dateien eines Package andere Units referenzieren, die ebenfalls in Packages enthalten sind, sollten diese anderen Packages im requires-Abschnitt des ersten Package angegeben werden. Andernfalls lädt der Compiler die referenzierten Units aus den entsprechenden .dcu-Dateien.

Zirkuläre Bezüge bei Packages vermeiden

Packages dürfen in ihren requires-Klauseln keine zirkulären Bezüge enthalten. Daher müssen folgende Bedingungen erfüllt sein:

  • Ein Package darf nicht in seiner eigenen requires-Klausel aufgeführt sein.
  • Eine Folge von Referenzen darf keine rückwärtsgerichtete Referenz enthalten. Wenn Package A in seinem requires-Abschnitt Package B referenziert, kann Package B nicht Package A referenzieren. Wenn Package A Package B und Package B Package C referenziert, kann C nicht A referenzieren.

Doppelte Package-Referenzen

Der Compiler ignoriert doppelte Referenzen in der requires-Klausel eines Package. Wegen der besseren Lesbarkeit Ihrer Programme sollten Sie derartige Referenzen aber entfernen.

Die contains-Klausel

In der contains-Klausel wird festgelegt, welche Unit-Dateien in das Package eingebunden werden sollen. Die contains-Klausel darf keine Dateinamenserweiterungen enthalten.

Redundante Verwendung von Quelltext vermeiden

Ein Package kann nicht in der contains-Klausel eines anderen Package oder in der uses-Klausel einer Unit enthalten sein.

Alle Units, die direkt in der contains-Klausel eines Package oder indirekt in uses-Klauseln der betreffenden Units enthalten sind, werden zur Compilierzeit in das Package eingebunden. Die Units, die (direkt oder indirekt) in einem Package vorhanden sind, dürfen in keinem der anderen Packages enthalten sein, die in der requires-Klausel dieses Package referenziert werden.

Eine Unit kann weder direkt noch indirekt in mehr als einem Package einer Anwendung enthalten sein.

Packages compilieren

Packages werden normalerweise in der IDE unter Verwendung von .dpk-Dateien compiliert, die mit der Projektverwaltung generiert werden. Sie können .dpk-Dateien auch direkt in der Befehlszeile compilieren. Bei der Neucompilierung eines Projekts, das ein Package enthält, wird dieses implizit neu compiliert, wenn dies erforderlich ist.

Generierte Dateien

Die folgende Tabelle enthält die Dateien, die beim erfolgreichen Compilieren eines Package generiert werden.

Dateien eines compilierten Package

Namenserweiterung Inhalt

DCP

Ein binäres Abbild, das einen Package-Header und die Verkettung aller .dcu-Dateien (Win32) des Package enthält. Für jedes Package wird eine .dcp- oder .dcpil-Datei erzeugt. Der Basisname der Datei entspricht dem Basisnamen der .dpk-Quelltextdatei.

BPL

Das Laufzeit-Package. In Win32 ist diese Datei eine DLL mit Embarcadero-spezifischen Eigenschaften. Der Basisname des Package entspricht dem Basisnamen der dpk-Quelltextdatei.

Package-spezifische Compiler-Direktiven

Die folgende Tabelle enthält die Package-spezifischen Compiler-Direktiven, die in den Quelltext eingefügt werden können.

Spezielle Compiler-Direktiven für Packages

Direktive Beschreibung

{$IMPLICITBUILD OFF}

Verhindert, dass ein Package in Zukunft implizit neu compiliert wird. Diese Direktive wird in .dpk-Dateien verwendet, wenn Packages mit Low-Level-Funktionen compiliert werden, die sich nur selten ändern, oder wenn der Quelltext des Package nicht weitergegeben wird.

{$G-} oder {$IMPORTEDDATA OFF}

Deaktiviert die Erstellung von Referenzen auf importierte Daten. Diese Direktive führt zu schnelleren Speicherzugriffen, verhindert aber, dass die Unit, in der sie verwendet wird, Variablen in anderen Packages referenzieren kann.

{$WEAKPACKAGEUNIT ON}

Die Unit wird schwach eingebunden.

{$DENYPACKAGEUNIT ON}

Verhindert, dass die Unit in ein Package eingebunden wird.

{$DESIGNONLY ON}

Das Package wird für die Installation in der IDE compiliert (nur in .dpk-Dateien).

{$RUNONLY ON}

Das Package wird nur als Laufzeit-Package compiliert (nur in .dpk-Dateien).


Die Verwendung von {$DENYPACKAGEUNIT ON} im Quelltext verhindert, dass die Unit in ein Package eingebunden wird. Die Angabe von {$G-} oder {$IMPORTEDDATA OFF} kann bewirken, dass das Package nicht zusammen mit anderen Packages in derselben Anwendung verwendet werden kann.

Bei Bedarf können auch andere Compiler-Direktiven in den Quelltext eines Package aufgenommen werden.

Package-spezifische Befehlszeilenoptionen

Die folgenden Package-spezifischen Optionen stehen für den Befehlszeilen-Compiler zur Verfügung.

Package-spezifische Befehlszeilenoptionen

Option Beschreibung

-$G-

Deaktiviert die Erstellung von Referenzen auf importierte Daten. Diese Option führt zu beschleunigten Speicherzugriffen, verhindert aber, dass mit dieser Option compilierte Packages Variablen in anderen Packages referenzieren.

LE Pfad

Gibt das Verzeichnis an, in dem die compilierte Package-Datei abgelegt wird.

LN Pfad

Gibt das Verzeichnis an, in dem die dcp- oder dcpil-Datei des Package abgelegt wird.

LUpackageName [;packageName2;...]

Gibt zusätzliche Laufzeit-Packages für die Verwendung in einer Anwendung an. Wird bei der Compilierung eines Projekts verwendet.

Z

Verhindert, dass ein Package in Zukunft implizit neu compiliert wird. Diese Option wird verwendet, wenn Packages mit Low-Level-Funktionen compiliert werden, die sich nur selten ändern, oder wenn der Quelltext des Package nicht weitergegeben wird.


Die Verwendung der Option -$G- kann zur Folge haben, dass ein Package nicht mehr zusammen mit anderen Packages in derselben Anwendung verwendet werden kann.

Bei Bedarf können für die Compilierung von Packages auch andere Befehlszeilenoptionen angegeben werden.

Siehe auch