Usando dllimport e dllexport em Classes C++
Específicos do Microsoft
Você pode declarar classes C++ com o dllimport ou dllexport atributo.Esses formulários implicam que toda a turma for importada ou exportada.Classes exportadas dessa maneira são chamados classes exportáveis.
O exemplo a seguir define uma classe de exportável.Todos os seus dados estáticos e funções de membro são exportados:
#define DllExport __declspec( dllexport )
class DllExport C {
int i;
virtual int func( void ) { return 1; }
};
Observe que o uso explícito da dllimport e dllexport atributos nos membros de uma classe exportável é proibido.
Classes de dllexport
Quando você declara uma classe dllexport, todos os membros de dados estáticos e suas funções de membro são exportados.Você deve fornecer 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 a funções virtuais puras, para o qual você não precisa fornecer definições explícitas.No entanto, porque um destruidor de uma classe abstrata é chamado, o destruidor de classe base, destruidores virtuais puros sempre forneça uma definição.Observe que essas regras são as mesmas para classes de nonexportable.
Se você exportar dados do tipo de classe ou funções que retornam classes, certifique-se de exportar a classe.
Classes de DllImport
Quando você declara uma classe dllimport, todas as suas funções de membro e membros de dados estáticos são importados.Ao contrário do comportamento de dllimport e dllexport nos tipos de nonclass, membros de dados estáticos não é possível especificar uma definição no mesmo programa no qual um dllimport classe é 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 é gerado.Além disso, todos os membros acessíveis que também são classes devem ser exportáveis.Essa regra permite uma dllexport classe herdar de uma dllimport classe e um dllimport classe herdar de uma dllexport de classe (embora o último não é recomendado).Como regra, tudo o que é acessível ao cliente da DLL (de acordo com a regras de acesso de C++) deve ser parte da interface do exportável.Isso inclui referenciados em funções internas de membros de dados particulares.
Importação e exportação de membro seletiva
Como funções de membro e dados estáticos dentro de uma classe implicitamente têm ligação externa, você pode declará-los com o dllimport ou dllexport de atributo, a menos que a classe inteira é exportada.Se toda a turma for importada ou exportada, a declaração explícita de funções de membro e dados como dllimport ou dllexport é proibido.Se você declara um membro de dados estáticos em uma definição de classe como dllexport, uma definição deve ocorrer em algum lugar dentro do mesmo programa (como com ligação externa de nonclass).
Da mesma forma, você pode declarar os membro funções com o dllimport ou dllexport atributos.Nesse caso, você deve fornecer um dllexport definição em algum lugar dentro do mesmo programa.
Vale a pena observar vários pontos importantes com relação ao membro seletiva de importação e exportação:
Membro seletiva de importação/exportação é melhor usada para fornecer uma versão da interface exportado de classe que é mais restritiva; ou seja, um para o qual você pode criar uma DLL que expõe menos recursos públicos e privados que a linguagem permitiria.Também é útil para ajustar a interface exportável: quando você sabe que o cliente, por definição, é impossível acessar alguns dados particulares, você não precisa exportar toda a turma.
Se você exportar uma função virtual em uma classe, você deve exportar todas elas ou pelo menos fornecem versões que o cliente pode usar diretamente.
Se você tiver uma classe na qual você estiver usando o membro seletiva de importação/exportação com funções virtuais, as funções devem estar na interface do exportável ou definido in-line (visível para o cliente).
Se você definir um membro como dllexport , mas não o inclua na definição de classe, é gerado um erro do compilador.Você deve definir o membro no cabeçalho da classe.
Embora a definição de membros de classe como dllimport ou dllexport é permitido, você não pode substituir a interface especificada na definição de classe.
Se você definir uma função de membro em um local diferente, por exemplo, o corpo da definição de classe no qual você declarou, um aviso é gerado se a função é definida como dllexport ou dllimport (se essa definição for diferente da que especificou na declaração da classe).