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