Aviso do compilador (nível 2) C4251
'type' : a classe 'type1' precisa ter uma interface dll a ser usada por clientes da classe 'type2'
Comentários
Esse aviso ocorre se uma classe estiver marcada com __declspec(dllexport)
ou __declspec(dllimport)
e um membro de dados não estático que seja membro da classe ou membro de uma de suas classes base, tiver um tipo que seja um tipo de classe que não esteja marcado com __declspec(dllexport)
ou __declspec(dllimport)
. Veja Exemplo.
Para minimizar a possibilidade de corrupção de dados ao exportar uma classe declarada como __declspec(dllexport)
, verifique se:
- Todos os dados estáticos são acessados por meio de funções exportadas da DLL.
- Nenhum método embutido da classe pode modificar dados estáticos.
- Nenhum método embutido de sua classe usa funções CRT ou outras funções de biblioteca que usam dados estáticos. Para obter mais informações, consulte Erros potenciais ao passar objetos CRT entre limites de DLL.
- Nenhum método de sua classe (independentemente de estar embutida) pode usar tipos em que a instanciação no EXE e na DLL tenha diferenças de dados estáticos.
Você pode evitar problemas ao exportar uma classe de uma DLL:
- Definindo sua classe para ter funções virtuais.
- Definindo um destruidor virtual.
- Definir funções para instanciar e excluir instâncias do tipo.
Você pode ignorar C4251 se sua classe for derivada de um tipo na Biblioteca Padrão C++, você estiver compilando uma versão de depuração (/MTd
) e a mensagem de erro do compilador se referir a _Container_base
.
Pense cuidadosamente sobre adicionar __declspec(dllexport)
ou __declspec(dllimport)
a uma classe porque quase sempre não é a escolha certa e pode dificultar a manutenção porque dificulta a alteração dos detalhes da implementação.
Exemplo
// 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
};
Para corrigir esse aviso, não marque a classe com __declspec(dllexport)
ou __declspec(dllimport)
. Em vez disso, marque apenas os métodos usados diretamente por um cliente. Por exemplo:
// 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;
};