Importação de chamadas de função usando __declspec(dllimport)
O exemplo de código a seguir mostra como usar _declspec(dllimport) para importar chamadas de função de uma DLL para um aplicativo.Suponha que func1 é uma função que reside em uma DLL separada do arquivo. exe que contém o principal função.
Sem __declspec(dllimport), dado este código:
int main(void)
{
func1();
}
o compilador gera código parecido com este:
call func1
e o vinculador converte a chamada em algo assim:
call 0x4000000 ; The address of 'func1'.
Se func1 existe em outra DLL, o vinculador não é possível resolver neste diretamente porque tem uma maneira de saber qual o endereço de func1 é.Em ambientes de 16 bits, o vinculador adiciona esse endereço de código para uma lista no arquivo. exe que o carregador deve patch em tempo de execução com o endereço correto.Em ambientes de 32 bits e 64 bits, o vinculador gera uma conversão que ele saiba o endereço.Em um ambiente de 32 bits a conversão é semelhante a:
0x40000000: jmp DWORD PTR __imp_func1
Aqui imp_func1 é o endereço para o func1 slot na tabela de endereços Importar do arquivo. exe.Assim, todos os endereços são conhecidos para o vinculador.O carregador tem apenas atualizar a tabela de endereços de importação do arquivo. exe no tempo de carregamento para que tudo funcione corretamente.
Portanto, usando __declspec(dllimport) é melhor porque o vinculador não gera uma conversão se não for necessário.Thunks tornar o código maiores (em sistemas RISC, pode ser várias instruções) e podem prejudicar o desempenho do cache.Se você informar o compilador que é a função em uma DLL, ele pode gerar uma chamada indireta para você.
Agora este código:
__declspec(dllimport) void func1(void);
int main(void)
{
func1();
}
gera esta instrução:
call DWORD PTR __imp_func1
Não há nenhuma conversão e não jmp instrução, portanto o código é menor e mais rápido.
Por outro lado, para chamadas de função dentro de uma DLL, não ser necessário usar uma chamada indireta.Você já sabe o endereço da função.Porque o tempo e espaço são necessários para carregar e armazenar o endereço da função antes de uma chamada indireta, uma chamada direta é sempre mais rápidos e menores.Você deseja usar __declspec(dllimport) ao chamar funções DLL de fora da própria DLL.Não use __declspec(dllimport) nas funções dentro de uma DLL ao criar essa DLL.