#pragma package

De Appmethod Topics
Aller à : navigation, rechercher

Remonter à Présentation des directives pragma - Index

Syntaxe (voir Pseudo-grammaire)

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

Description

#pragma package(smart_init)

#pragma package(smart_init) garantit l'initialisation des unités packagées dans l'ordre déterminé par leurs dépendances (incluses par défaut dans le fichier source du package). Typiquement, utilisez #pragma package pour les fichiers .cpp construits comme des packages.

Remarque : N'utilisez pas #pragma package(smart_init) dans un fichier d'en-tête. Si vous le faites, vous obtiendrez l'erreur de compilation E2177 Redéclaration de #pragma package avec différents arguments (C++).

Cette directive pragma affecte l'ordre d'initialisation de l'unité de compilation. Pour les unités, l'initialisation se produit dans l'ordre suivant :

  1. Selon leurs dépendances "uses". Ainsi, si l'unitéA dépend de l'unitéB, l'unitéB doit être initialisée avant l'unitéA.
  2. Selon l'ordre de lien.
  3. Selon l'ordre de priorité au sein de l'unité.

Pour les fichiers objet normaux (ceux non construits comme des unités), l'initialisation se produit d'abord en fonction de l'ordre de priorité puis de l'ordre de lien. La modification de l'ordre de lien des fichiers objet modifie l'ordre dans lequel les constructeurs d'objets globaux sont appelés.

Les exemples suivants illustrent en quoi l'initialisation des unités diffère de celle des fichiers objet normaux.

Exemple

Supposons que vous disposez de trois fichiers source, A, B et C, qui sont "initialisés intelligemment" avec #pragma package(smart_init) et de fonctions avec des valeurs de priorité définies sur 10, 20 et 30 (définies par le paramètre priorité du #pragma startup). Les fonctions sont nommées selon leur valeur de priorité et le fichier source parent, les noms sont ainsi a10, a20, a30, b10, b20, et ainsi de suite.

Voici les trois programmes A, B et 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

Si vous construisez les fichiers source comme écrit et avec USE_PACKAGE_INIT défini, vous obtenez l'impression suivante :

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

Ainsi, la priorité est ignorée et toutes les initialisations de chaque unité sont exécutées en une seule fois.

Vous obtiendrez un résultat complètement différent si vous construisez les fichiers source sans USE_PACKAGE_INIT défini. Dans ce cas, lorsque vous exécutez le programme, vous obtenez l'impression suivante :

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

Notez que la priorité startup est utilisée.

Puisque les trois fichiers sont des unités, et en supposant que A utilise B et C et que l'ordre de lien est A, B puis C, l'ordre d'initialisation est : B10() B20() B30() C10() C20() C30() A10() A20() A30()

S'il s'agissait de fichiers objet, et non d'unités, l'ordre serait : A10() B10() C10() A20() B20() C20() A30() B30() C30()

Les fichiers .cpp qui utilisent #pragma package(smart_init) requièrent également que toutes les références #pragma link à d'autres fichiers objet à partir d'un fichier .cpp qui déclare #pragma package(smart_init) doivent être résolues par une unité. Les références #pragma link à des fichiers non objet peuvent toujours être résolues par des bibliothèques, et ainsi de suite.

#pragma package(smart_init, weak)

La directive #pragma package(smart_init, weak) affecte la manière dont un fichier objet est stocké dans les fichiers .bpi et .bpl d'un package. Si #pragma package(smart_init, weak) apparaît dans un fichier unité, le compilateur omet l'unité dans les fichiers BPL quand c'est possible, et crée une copie locale non packagée de l'unité quand elle est requise par une autre application ou un autre package. Une unité compilée avec cette directive est dite "faiblement packagée".

#pragma package(smart_init, weak) est utilisé pour éliminer les conflits entre des packages pouvant dépendre de la même bibliothèque externe.

Les fichiers unité contenant la directive #pragma package(smart_init, weak) ne doivent pas contenir de variables globales.

Pour de plus amples informations sur l'utilisation de packages faibles, voir Packaging faible.

Voir aussi