#pragma package

Aus Appmethod Topics
Wechseln zu: Navigation, Suche

Nach oben zu Pragma-Direktiven (Übersicht) - Index

Syntax (siehe Pseudogrammatik)

#pragma package(smart_init)
#pragma package(smart_init, weak)

Beschreibung

#pragma package(smart_init)

Die Anweisung #pragma package(smart_init) stellt sicher, dass gepackte Units in der Reihenfolge initialisiert werden, die durch ihre Abhängigkeiten (standardmäßig in der Package-Quelldatei enthalten) festgelegt ist. Normalerweise setzen Sie #pragma package für CPP-Dateien ein, die als Packages erzeugt werden.

Hinweis: Verwenden Sie #pragma package(smart_init) nicht in Header-Dateien. Dies könnte zum Compiler-Fehler E2177 Redeklaration von #pragma package mit verschiedenen Argumenten (C++) führen.

Dieses Pragma wirkt sich auf die Reihenfolge der Initialisierung dieser Compilierungs-Unit aus. Units werden in folgender Reihenfolge initialisiert:

  1. Nach ihren "uses"-Abhängigkeiten, d. h., wenn UnitA von UnitB abhängt, muss UnitB vor UnitA initialisiert werden.
  2. Nach der Link-Reihenfolge.
  3. Nach der Priorität innerhalb der Unit.

Reguläre OBJ-Dateien (solche, die nicht als Units erzeugt werden) werden zuerst nach der Priorität und dann nach der Link-Reihenfolge initialisiert. Wenn Sie die Reihenfolge der Objektdateien ändern, werden die Konstruktoren der globalen Objekte in der entsprechenden Reihenfolge aufgerufen.

Die folgenden Beispiele zeigen die Unterschiede der Initialisierung bei Units und regulären Objektdateien.

Beispiel

Sie haben beispielsweise drei Quelldateien A, B und C, die mit #pragma package(smart_init) initialisiert wurden und über Funktionen mit den Prioritätswerten 10, 20 und 30 (definiert durch den Prioritätsparameter von #pragma startup) verfügen. Die Funktionen sind entsprechend ihrer Prioritätswerte und der zugehörigen Quelldatei als a10, a20, a30, b10, b20 usw. benannt.

Hier sind die drei Programme A, B und C:

 // A.cpp
 #include <stdio.h>
 
 #ifdef USE_PACKAGE_INIT
 #pragma package(smart_init)
 #endif
 
 void A10() {
   printf("%s() ", __FUNCTION__);
 }
 #pragma startup A10 10
 
 void A20() {
   printf("%s() ", __FUNCTION__);
 }
 #pragma startup A20 20
 
 void A30() {
   printf("%s() ", __FUNCTION__);
 }
 #pragma startup A30 30
 // B.cpp
 #include <stdio.h>
 
 #ifdef USE_PACKAGE_INIT
 #pragma package(smart_init)
 #endif
 
 void B10() {
   printf("%s() ", __FUNCTION__);
 }
 #pragma startup B10 10
 
 void B20() {
   printf("%s() ", __FUNCTION__);
 }
 #pragma startup B20 20
 
 void B30() {
   printf("%s() ", __FUNCTION__);
 }
 #pragma startup B30 30
 // C.cpp
 #include <stdio.h>
 
 #ifdef USE_PACKAGE_INIT
 #pragma package(smart_init)
 #endif
 
 void C10() {
   printf("%s() ", __FUNCTION__);
 }
 #pragma startup C10 10
 
 void C20() {
   printf("%s() ", __FUNCTION__);
 }
 #pragma startup C20 20
 
 void C30() {
   printf("%s() ", __FUNCTION__);
 }
 #pragma startup C30 30

Wenn Sie die Quelldateien so, wie sie geschrieben sind, und mit definierter Anweisung USE_PACKAGE_INIT erzeugen, erhalten Sie die folgende Ausgabe:

A10() A20() A30() B10() B20() B30() C10() C20() C30()

Das heißt, dass die Priorität ignoriert wird und für jede Unit die gesamte Initialisierung auf einmal durchgeführt wird.

Sie erhalten ein vollständig anderes Ergebnis, wenn Sie die Quelldateien ohne USE_PACKAGE_INIT erzeugen. In diesem Fall wird bei Ausführung des Programms Folgendes ausgegeben:

A10() B10() C10() A20() B20() C20() A30() B30() C30()

Das heißt, dass die anfängliche Priorität verwendet wird.

Da es sich bei allen dreien um Units handelt, und wenn A B und C verwendet, und die Link-Reihenfolge A, B dann C ist, ergibt sich die Initialisierungsreihenfolge: B10() B20() B30() C10() C20() C30() A10() A20() A30()

Bei Objektdateien anstelle von Units ergibt sich die folgende Reihenfolge: A10() B10() C10() A20() B20() C20() A30() B30() C30()

Für CPP-Dateien, die #pragma package(smart_init) verwenden, ist es auch erforderlich, dass alle #pragma link-Referenzen zu anderen Objektdateien von einer CPP-Datei aus, die #pragma package(smart_init) deklariert, durch eine Unit aufgelöst werden. #pragma link-Referenzen auf Nicht-Objektdateien können auch durch Bibliotheken usw. aufgelöst werden.

#pragma package(smart_init, weak)

Die Direktive #pragma package(smart_init, weak) beeinflusst die Art, wie eine Objektdatei in BPI- und BPL-Dateien eines Packages gespeichert wird. Wenn #pragma package(smart_init, weak) in einer Unit-Datei enthalten ist, lässt der Compiler, wenn möglich, die Unit aus BPLs weg. Der Compiler legt eine lokale Kopie der Unit (ohne Package) an, wenn die Unit für eine andere Anwendung oder ein anderes Package erforderlich ist. Eine solche Unit bezeichnet man als "schwach gepackt".

#pragma package(smart_init, weak) wird verwendet, um Konflikte zwischen Packages auszuschließen, die von derselben externen Bibliothek abhängen könnten.

Unit-Dateien mit der Direktive #pragma package(smart_init, weak) dürfen keine globalen Variablen enthalten.

Weitere Informationen hierzu finden Sie unter Schwaches Packen.

Siehe auch