Utilisation de la directive de packaging faible
Remonter à Compilation de packages
Les unités faibles (faiblement packagées) sont des unités définies dans un package (c'est-à-dire un projet package). Toutefois, la liaison est différente pour les packages liés de façon dynamique.
Normalement, une unité réside dans le package lui-même. Lorsqu'il est lié, le fichier BPI (bibliothèque d'importation de package) crée une référence au package.
En revanche, une unité faiblement packagée réside dans le fichier BPI. Cela signifie que même pour un package lié de façon dynamique, une unité faiblement packagée est directement liée au module consommateur du package. Tout aussi important, si vous mettez à jour le fichier BPL à un autre moment que pendant la recompilation du logiciel à l'aide du fichier BPL, l'unité faiblement packagée supposément contenue dans le fichier BPL n'est pas mise à jour dans le logiciel qui l'utilise, car elle se trouve en fait dans la bibliothèque d'importation (BPI) et est donc liée dans le consommateur du package.
Si vous utilisez seulement une unité faible à partir d'un package, votre application ne dépendra pas de ce package (vous ne disposerez donc pas d'une dépendance par rapport au fichier BPL). En effet, au lieu d'un objet d'importation, le fichier BPI contient le fichier objet de l'unité (comme s'il s'agissait d'un package statique), et comme le fichier objet est lié, il n'est pas dépendant du package. En d'autres termes, les unités faiblement packagées créent un mélange de packages dynamiques et statiques, où les unités faibles sont statiques.
Voici des exemples qui décrivent ce comportement pour Delphi et C++Builder :
Delphi
La directive $WEAKPACKAGEUNIT
affecte la manière dont un fichier .dcu
est stocké dans des fichiers .dcp
et .bpl
d'un package.
Si {$WEAKPACKAGEUNIT ON}
figure 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.
Par exemple, supposez que vous ayez créé un package appelé pack1 qui contient une seule unité, unit1. Supposez que unit1 n'utilise aucune unité supplémentaire, mais fait des appels à rare.dll. Si vous placez la directive {$WEAKPACKAGEUNIT ON}
dans unit1.pas (Delphi) ou unit1.cpp (C++), lors de la compilation du package, unit1 n'est pas incluse dans pack1.bpl ; vous n'avez donc pas à distribuer de copie de rare.dll avec pack1. Cependant, unit1 sera toujours incluse dans pack1.dcp. Si un autre package ou une autre application utilisant pack1 fait référence à unit1, elle sera copiée depuis pack1.dcp et compilée directement dans le projet.
Supposons maintenant que vous ajoutiez à pack1 une deuxième unité, unit2, et que unit2 utilise unit1. Cette fois, même si vous compilez pack1 avec {$WEAKPACKAGEUNIT ON}
dans unit1.pas, le compilateur inclura unit1 dans pack1.bpl.
{$WEAKPACKAGEUNIT ON}
ne doivent pas contenir de variables globales, de section d'initialisation ou de section de finalisation.La directive {$WEAKPACKAGEUNIT ON}
est une fonctionnalité avancée à l'intention des développeurs distribuant leurs packages à d'autres programmeurs. Elle vous permet d'éviter la distribution de DLL rarement utilisées et supprime les conflits entre des packages qui peuvent dépendre de la même bibliothèque externe.
Ainsi, l'unité PenWin référence PenWin.dll. La plupart des projets n'utilisent pas PenWin et la plupart des ordinateurs n'ont pas de fichier PenWin.dll installé. C'est pour cela que l'unité PenWin est faiblement packagée dans vcl. Lorsque vous compilez un projet utilisant PenWin et le package vcl, PenWin est copiée depuis vcl70.dcp et liée directement dans votre projet ; l'exécutable résultant est statiquement lié à PenWin.dll.
Si PenWin n'avait pas été faiblement packagée, deux problèmes se seraient produits. Tout d'abord, il aurait fallu que la VCL soit liée de manière statique à PenWin.dll et vous n'auriez donc pas pu le charger sur un système ne disposant pas de PenWin.dll. De plus, si vous aviez tenté de créer un package contenant PenWin, une erreur de compilation aurait eu lieu, puisque l'unité PenWin est contenue dans la VCL et dans votre package. Ainsi, sans "packaging faible", l'unité PenWin n'aurait pas pu être incluse dans des distributions standard de la VCL.
C++Builder
La directive #pragma package(smart_init, weak)
affecte la manière dont un fichier .obj est stocké dans les fichiers .bpi et .bpl d'un package. (Pour davantage d'informations sur les fichiers générés par le compilateur et le lieur, voir Packages et DLL standard.) Si #pragma package(smart_init, weak)
figure dans un fichier unité, le lieur ne place pas l'unité dans les fichiers bpl si c'est possible, et crée une copie locale non packagée de l'unité si elle est nécessaire à une autre application ou un autre package. Une unité compilée avec cette directive est dite "faiblement packagée".
Supposons, par exemple, que vous avez créé un package appelé PACK ne contenant qu'une seule unité UNIT1, et que UNIT1 n'utilise aucune autre unité mais effectue des appels à RARE.dll. Si vous placez #pragma package(smart_init, weak)
dans UNIT1.cpp lorsque vous construisez votre package, UNIT1 ne sera pas incluse dans PACK.bpl ; vous n'aurez pas à distribuer de copies de RARE.dll avec PACK. Cependant, UNIT1 sera toujours incluse dans PACK.bpi. Si un autre package ou une autre application utilisant PACK fait référence à UNIT1, celle-ci sera copiée à partir de PACK.bpi et liée directement dans le projet.
Supposons maintenant que vous ajoutiez à PACK une deuxième unité, UNIT2, et que UNIT2 utilise UNIT1. Cette fois, même si vous compilez PACK avec #pragma package(smart_init, weak)
dans UNIT1.cpp, le lieur inclura UNIT1 dans PACK.bpl. Mais d'autres packages ou applications faisant référence à UNIT1 utiliseront la copie (non packagée) extraite de PACK.bpi.
#pragma package(smart_init, weak)
ne doivent pas contenir de variables globales.#pragma package(smart_init, weak)
est une caractéristique avancée prévue pour les programmeurs qui distribuent leurs fichiers bpl à d'autres programmeurs C++Builder. Elle vous permet d'éviter la distribution de DLL rarement utilisées et supprime les conflits entre des packages qui peuvent dépendre de la même bibliothèque externe.
Ainsi, l'unité PenWin référence PenWin.dll. La plupart des projets n'utilisent pas PenWin et la plupart des ordinateurs n'ont pas de fichier PenWin.dll installé. C'est pour cela que l'unité PenWin est faiblement packagée dans vcl. Lorsque vous liez un projet utilisant PenWin et le package vcl, PenWin est copiée depuis vcl60.bpi et liée directement dans votre projet ; l'exécutable résultant est statiquement lié à PenWin.dll.
Si PenWin n'avait pas été faiblement packagée, deux problèmes se seraient produits. Tout d'abord, il aurait fallu que vcl soit lié de manière statique à PenWin.dll et vous n'auriez donc pas pu le charger sur un ordinateur ne disposant pas de PenWin.dll. De plus, si vous tentez de créer un package contenant PenWin, une erreur de construction aurait lieu, puisque l'unité PenWin serait contenue dans vcl et dans votre package. Ainsi, sans "packaging faible", l'unité PenWin n'aurait pas pu être incluse dans les distributions standard de vcl.
Pour de plus amples informations, voir la documentation C++ sur #pragma package(smart_init, weak) la documentation Delphi sur le packaging faible et la directive de packaging faible.