Partager via


Avertissement du compilateur (niveau 2) C4251

'type' : la classe 'type1' doit disposer d’une interface DLL pour être utilisée par les clients de la classe 'type2'

Notes

Cet avertissement survient lorsqu’une classe est marquée avec __declspec(dllexport) ou __declspec(dllimport) et qu’un membre de données non statique qui est membre de la classe, ou un membre de l’une de ses classes de base, dispose d’un type qui est un type de classe non marqué avec __declspec(dllexport) ou __declspec(dllimport). Consultez l'exemple.

Pour réduire la possibilité d’altération des données lors de l’exportation d’une classe déclarée en tant que __declspec(dllexport), assurez-vous que :

  • Toutes vos données statiques sont accessibles via des fonctions exportées à partir de la DLL.
  • Aucune méthode inlined de votre classe ne peut modifier les données statiques.
  • Aucune méthode inlined de votre classe n’utilise de fonctions CRT ou d’autres fonctions de bibliothèque qui utilisent des données statiques. Pour plus d’informations, consultez Erreurs potentielles de passage d’objets CRT entre les frontières DLL.
  • Aucune méthode de votre classe (inlined ou non) ne peut utiliser de types où l’instanciation dans l’EXE et la DLL présentent des différences de données statiques.

Vous pouvez éviter des problèmes lors de l’exportation d’une classe à partir d’une DLL en :

  • Définissant votre classe pour qu’elle ait des fonctions virtuelles.
  • Définissant un destructeur virtuel.
  • Définissant des fonctions pour instancier et supprimer des instances du type.

Vous pouvez ignorer C4251 si votre classe est dérivée d’un type dans la bibliothèque standard C++, si vous compilez une version de débogage (/MTd) et si le message d’erreur du compilateur fait référence à _Container_base.

Réfléchissez soigneusement à l’ajout de __declspec(dllexport) ou __declspec(dllimport) à une classe, car ce n’est quasiment jamais le bon choix et cela peut rendre la maintenance plus difficile, car cet ajout complique la modification des détails d’implémentation.

Exemple

// C4251.cpp
// Compile with /std:c++20 /EHsc /W2 /c C4251.cpp
#include <vector>
 
class __declspec(dllexport) X
{
public:
    X();
    ~X();
 
    void do_something();
 
private:
    void do_something_else();
    std::vector<int> data; // warning c4251
};

Pour corriger cet avertissement, ne marquez pas la classe avec __declspec(dllexport) ou __declspec(dllimport). Choisissez plutôt de marquer uniquement les méthodes utilisées directement par un client. Par exemple :

// C4251_fixed.cpp
// Compile with /std:c++20 /EHsc /W2 /c C4251-fixed.cpp
#include <vector>
 
class X
{
public:
    __declspec(dllexport) X();
    __declspec(dllexport) ~X();
 
    __declspec(dllexport) void do_something();
 
private:
    void do_something_else();
    std::vector<int> data;
};