Sur cette page

Création de bibliothèques partagées

Les sections suivantes répertorient certains éléments à prendre en compte lors de la création de bibliothèques partagées.

Utilisation des symboles des bibliothèques partagées

Les symboles (fonctions, variables ou classes) contenus dans les bibliothèques partagées destinées à être utilisées par des clients, tels que des applications ou d’autres bibliothèques, doivent être marqués d’une manière particulière. Ces symboles sont appelés symboles publics: ils sont exportés ou rendus visibles publiquement.

Les autres symboles ne doivent pas être visibles de l’extérieur. Sur la plupart des plateformes, les compilateurs les masquent par défaut. Sur certaines plateformes, une option de compilation spécifique est nécessaire pour masquer ces symboles.

Lors de la compilation d’une bibliothèque partagée, celle-ci doit être marquée pour l’exportation. Pour utiliser la bibliothèque partagée depuis un client, certaines plateformes peuvent également nécessiter une déclaration d’importation spécifique.

En fonction de votre plateforme cible, Qt fournit des macros spéciales contenant les définitions nécessaires :

  • Q_DECL_EXPORT doivent être ajoutées aux déclarations des symboles utilisés lors de la compilation d’une bibliothèque partagée.
  • Q_DECL_IMPORT doit être ajouté aux déclarations des symboles utilisés lors de la compilation d’un client qui utilise la bibliothèque partagée.

Il faut maintenant s’assurer que la bonne macro est invoquée, que l’on compile la bibliothèque partagée elle-même ou simplement le client utilisant cette bibliothèque. En général, cela peut être résolu en ajoutant un en-tête spécial.

Supposons que nous souhaitions créer une bibliothèque partagée nommée mysharedlib. Un en-tête spécifique à cette bibliothèque, mysharedlib_global.h, se présente comme suit :

#include <QtCore/QtGlobal>

#if defined(MYSHAREDLIB_LIBRARY)
#  define MYSHAREDLIB_EXPORT Q_DECL_EXPORT
#else
#  define MYSHAREDLIB_EXPORT Q_DECL_IMPORT
#endif

Dans chaque fichier d'en-tête de la bibliothèque, nous spécifions ce qui suit :

#include "mysharedlib_global.h"

MYSHAREDLIB_EXPORT void foo();
class MYSHAREDLIB_EXPORT MyClass...

Nous devons ensuite nous assurer que ` MYSHAREDLIB_LIBRARY ` est défini pour le compilateur lors de la compilation de la bibliothèque elle-même. Cela se fait dans le système de construction de la bibliothèque. Si nous utilisons CMake, nous complétons la cible de la bibliothèque partagée :

target_compile_definitions(mysharedlib PRIVATE MYSHAREDLIB_LIBRARY)

Si nous utilisons qmake, nous ajoutons

DEFINES += MYSHAREDLIB_LIBRARY

au fichier .pro de la bibliothèque partagée.

Remarque : Les assistants de bibliothèque dans Qt Creator et Qt VS Tools vous fournissent un squelette qui configure ces éléments à votre place.

Considérations relatives aux fichiers d'en-tête

En règle générale, les clients n'incluront que les fichiers d'en-tête publics des bibliothèques partagées. Ces bibliothèques peuvent être installées à un emplacement différent lors de leur déploiement. Il est donc important d'exclure les autres fichiers d'en-tête internes utilisés lors de la compilation de la bibliothèque partagée.

Par exemple, la bibliothèque peut fournir une classe qui encapsule un périphérique matériel et contient un descripteur vers ce périphérique, fourni par une bibliothèque tierce :

#include <footronics/device.h>

class MyDevice {
private:
    FOOTRONICS_DEVICE_HANDLE handle;
};

Une situation similaire se présente avec les formulaires créés par Qt Widgets Designer lors de l’utilisation de l’agrégation ou de l’héritage multiple :

#include "ui_widget.h"

class MyWidget : public QWidget {
private:
    Ui::MyWidget m_ui;
};

Lors du déploiement de la bibliothèque, il ne doit y avoir aucune dépendance vis-à-vis des en-têtes internes ` footronics/device.h ` ou ` ui_widget.h`.

Cela peut être évité en utilisant l’idiome du « pointeur vers l’implémentation » décrit dans divers ouvrages de programmation C++. Pour les classes à sémantique de valeur, envisagez d’utiliser ` QSharedDataPointer`.

Compatibilité binaire

Pour que les clients chargeant une bibliothèque partagée fonctionnent correctement, la disposition en mémoire des classes utilisées doit correspondre exactement à celle de la version de la bibliothèque utilisée pour compiler le client. En d’autres termes, la bibliothèque trouvée par le client lors de l’exécution doit être compatible binaire avec la version utilisée lors de la compilation.

Cela ne pose généralement pas de problème si le client est un progiciel autonome livré avec toutes les bibliothèques dont il a besoin.

Cependant, si l'application cliente s'appuie sur une bibliothèque partagée appartenant à un autre paquet d'installation ou au système d'exploitation, il faut alors réfléchir à un schéma de gestion des versions pour les bibliothèques partagées et décider à quel niveau la compatibilité binaire doit être maintenue. Par exemple, les bibliothèques Qt portant le même numéro de version majeur sont garanties compatibles binaires.

Le maintien de la compatibilité binaire impose certaines restrictions quant aux modifications que vous pouvez apporter aux classes. Vous trouverez une bonne explication à ce sujet sur la page KDE - Policies/Binary Compatibility Issues With C++. Ces aspects doivent être pris en compte dès le début de la conception de la bibliothèque. Nous recommandons d’utiliser, dans la mesure du possible, le principe du masquage de l’information et la technique du pointeur vers l’implémentation.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.