#pragma package

De RAD Studio
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 disposiez 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 la sortie 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 que USE_PACKAGE_INIT soit défini. Dans ce cas, lorsque vous exécutez le programme, vous obtenez la sortie 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) soient 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 d'unités 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 Utilisation de $WEAKPACKAGEUNIT.

Voir aussi