Sdílet prostřednictvím


Upozornění kompilátoru (úroveň 2) C4251

'typ': 'type1' musí mít DLL rozhraní, aby jej mohli používat klienti 'type2'

Poznámky

K tomuto upozornění dochází v případě, že je třída označená __declspec(dllexport) nebo __declspec(dllimport), a nestatický datový člen, který je členem této třídy nebo jedné z jejích základních tříd, má typ třídy, která není označena __declspec(dllexport) nebo __declspec(dllimport). Viz příklad.

Chcete-li minimalizovat možnost poškození dat při exportu třídy deklarované jako __declspec(dllexport), ujistěte se, že:

  • Všechna statická data jsou přístupná prostřednictvím funkcí, které jsou exportovány z knihovny DLL.
  • Statické data nemohou upravovat žádné vložené metody vaší třídy.
  • Žádné vložené metody vaší třídy používají funkce CRT nebo jiné funkce knihovny, které používají statická data. Další informace naleznete v tématu Potenciální chyby při předávání objektů CRT přes hranice DLL.
  • Žádná metoda vaší třídy (ať už vložená nebo ne) nesmí používat typy, pokud při jejich instanciaci v EXE a DLL existují rozdíly ve statických datech.

Můžete se vyhnout problémům při exportu třídy z knihovny DLL:

  • Definovat třídu, aby obsahovala virtuální funkce.
  • Definování virtuálního destruktoru
  • Definování funkcí pro vytvoření a odstranění instancí typu

C4251 můžete ignorovat, pokud je vaše třída odvozena od typu ve standardní knihovně C++, kompilujete ladicí verzi (/MTd) a chybová zpráva kompilátoru odkazuje na _Container_base.

Pečlivě zvažte přidání __declspec(dllexport) nebo __declspec(dllimport) do třídy, protože to téměř nikdy není tou správnou volbou a může to ztížit údržbu, protože změna podrobností implementace se tím stává obtížnější.

Příklad

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

Pokud chcete toto upozornění opravit, neoznačíte třídu znakem __declspec(dllexport) nebo __declspec(dllimport). Místo toho označte pouze metody, které klient používá přímo. Příklad:

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