Condividi tramite


Avviso del compilatore (livello 2) C4251

'type': la classe 'type1' deve avere dll-interface da usare dai client della classe 'type2'

Osservazioni:

Questo avviso si verifica se una classe è contrassegnata con __declspec(dllexport) o __declspec(dllimport) e un membro dati non statico membro della classe o di un membro di una delle relative classi di base, ha un tipo che è un tipo di classe non contrassegnato con __declspec(dllexport) o __declspec(dllimport). Vedere Esempio.

Per ridurre al minimo la possibilità di danneggiamento dei dati durante l'esportazione di una classe dichiarata come __declspec(dllexport), assicurarsi che:

  • Tutti i dati statici sono accessibili tramite funzioni esportate dalla DLL.
  • Nessun metodo inlined della classe può modificare i dati statici.
  • Nessun metodo inlined della classe usa funzioni CRT o altre funzioni di libreria che usano dati statici. Per altre informazioni, vedere Potenziali errori che passano oggetti CRT attraverso limiti DLL.
  • Nessun metodo della classe (inlined o meno) può usare i tipi in cui l'istanza di EXE e DLL presenta differenze di dati statici.

È possibile evitare problemi durante l'esportazione di una classe da una DLL tramite:

  • Definizione della classe per avere funzioni virtuali.
  • Definizione di un distruttore virtuale.
  • Definizione delle funzioni per creare un'istanza ed eliminare istanze del tipo.

È possibile ignorare C4251 se la classe è derivata da un tipo nella libreria standard C++, si sta compilando una versione di debug (/MTd) e il messaggio di errore del compilatore fa riferimento a _Container_base.

Pensa attentamente all'aggiunta __declspec(dllexport) o __declspec(dllimport) a una classe perché non è sempre la scelta giusta e può rendere più difficile la manutenzione perché rende più difficile modificare i dettagli di implementazione.

Esempio

// 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
};

Per correggere questo avviso, non contrassegnare la classe con __declspec(dllexport) o __declspec(dllimport). Contrassegnare invece solo i metodi usati direttamente da un client. Ad esempio:

// 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;
};