Usando o dllimport e o dllexport nas classes do C++
Seção específica da Microsoft
É possível declarar classes de C++ com o atributo dllimport
ou dllexport
. Esses formulários implicam que a classe inteira será importada ou exportada. As classes exportadas dessa maneira são chamadas classes exportáveis.
O exemplo a seguir define uma classe exportável. Todas as suas funções de membro e dados estáticos são exportados:
#define DllExport __declspec( dllexport )
class DllExport C {
int i;
virtual int func( void ) { return 1; }
};
O uso explícito dos atributos dllimport
e dllexport
em membros de uma classe exportável é proibido.
dllexport Classes
Ao declarar uma classe dllexport
, todos os seus membros de dados estáticos e funções membro são exportados. Você deve fornecer as definições de todos esses membros no mesmo programa. Caso contrário, será gerado um erro de vinculador. A única exceção a essa regra se aplica às funções virtuais puras, para as quais você não precisa fornecer definições explícitas. No entanto, como um destruidor de uma classe abstrata é sempre chamado pelo destruidor da classe base, os destruidores virtuais puros devem fornecer sempre uma definição. Essas regras são as mesmas para classes não exportáveis.
Se você exportar dados do tipo de classe ou de funções que retornarem classes, exporte a classe.
dllimport Classes
Ao declarar uma classe dllimport
, todos os seus membros de dados estáticos e funções membro são importados. Ao contrário do comportamento de dllimport
e dllexport
em tipos sem classe, os membros de dados estáticos não podem especificar uma definição no mesmo programa em que uma classe dllimport
é definida.
Herança e classes exportáveis
Todas as classes base de uma classe exportável devem ser exportáveis. Caso contrário, um aviso do compilador será gerado. Além disso, todos os membros acessíveis que também são classes devem ser exportáveis. Essa regra permite que uma classe dllexport
herde de uma classe dllimport
e que uma classe dllimport
herde de uma classe dllexport
(embora a última não seja recomendada). Como regra, tudo que pode ser acessado pelo cliente da DLL (de acordo com as regras de acesso do C++) deve fazer parte da interface exportável. Isso inclui os membros de dados confidenciais referenciados em funções integradas.
Importação/Exportação de Membros Seletivos
Como as funções de membro e os dados estáticos dentro de uma classe têm implicitamente vinculação externa, você pode declará-las com o atributo dllimport
ou dllexport
, a menos que a classe inteira seja exportada. Se a classe inteira for importada ou exportada, a declaração explícita das funções de membro e dados como dllimport
ou dllexport
será proibida. Se você declarar um membro de dados estáticos em uma definição de classe como dllexport
, deverá ocorrer uma definição em algum lugar no mesmo programa (assim como ocorre na vinculação externa sem classe).
Da mesma forma, você pode declarar funções de membro com os atributos dllimport
ou dllexport
. Nesse caso, você deve fornecer uma definição de dllexport
em algum lugar dentro do mesmo programa.
Vale a pena observar vários pontos importantes sobre a importação e a exportação seletiva de membros:
A importação/exportação seletiva de membros é melhor usada para o fornecimento de uma versão da interface de classe exportada mais restritiva, isto é, uma para a qual você pode criar uma DLL que exponha menos recursos públicos e particulares do que a linguagem normalmente permitiria. Também é útil para ajustar a interface exportável: quando você souber que o cliente, por definição, não pode acessar alguns dados particulares, não precisará exportar a classe inteira.
Se você exportar uma função virtual em uma classe, deverá exportar todas elas ou pelo menos fornecer versões que poderão ser diretamente usadas pelo cliente.
Se você tiver uma classe em que usa a importação/exportação seletiva de membros com funções virtuais, as funções deverão estar na interface exportável ou ser definidas como integradas (podem ser vistas pelo cliente).
Se você definir um membro como
dllexport
mas não incluí-lo na definição de classe, um erro do compilador será gerado. Você deve definir o membro no cabeçalho da classe.Embora a definição de membros de classe como
dllimport
oudllexport
seja permitida, não é possível substituir a interface especificada na definição de classe.Se você definir uma função de membro em um lugar que não seja o corpo da definição de classe na qual você a declarou, um aviso será gerado se a função for definida como
dllexport
oudllimport
(se essa definição for diferente da especificada na declaração da classe).
Fim da seção específica da Microsoft
Confira também
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de