Dela via


Kompilatorvarning (nivå 2) C4251

"type": "type1" måste ha dll-gränssnitt som ska användas av klienter av "type2"

Anmärkningar

Den här varningen inträffar om en klass är markerad med __declspec(dllexport) eller __declspec(dllimport) och en icke-statisk datamedlem som är medlem i klassen eller medlem i en av dess basklasser, har en typ som är en klasstyp som inte är markerad med __declspec(dllexport) eller __declspec(dllimport). Se Exempel.

För att minimera risken för skadade data när du exporterar en klass som deklarerats som __declspec(dllexport), kontrollerar du att:

  • Alla dina statiska data nås via funktioner som exporteras från DLL:en.
  • Inga infogade metoder i klassen kan ändra statiska data.
  • Inga ingående metoder i klassen använder CRT-funktioner eller andra biblioteksfunktioner som använder statiska data. Mer information finns i Potentiella fel som skickar CRT-objekt över DLL-gränser.
  • Inga metoder i klassen (oavsett om de är inlindade eller inte) kan använda typer där instansieringen i EXE och DLL har statiska dataskillnader.

Du kan undvika problem när du exporterar en klass från en DLL genom att:

  • Definiera klassen så att den har virtuella funktioner.
  • Definiera en virtuell destruktor.
  • Definiera funktioner för att instansiera och ta bort instanser av typen.

Du kan ignorera C4251 om klassen härleds från en typ i C++-standardbiblioteket, du kompilerar en felsökningsversion (/MTd) och kompilatorns felmeddelande refererar till _Container_base.

Tänk noga på att lägga till __declspec(dllexport) eller __declspec(dllimport) till en klass eftersom det nästan alltid inte är rätt val och det kan göra underhåll svårare eftersom det gör det svårare att ändra implementeringsinformationen.

Exempel

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

Om du vill åtgärda den här varningen markerar du inte klassen med __declspec(dllexport) eller __declspec(dllimport). Markera i stället bara de metoder som används direkt av en klient. Till exempel:

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