A importação de chamadas de função usando __declspec(dllimport)

O exemplo de código a seguir mostra como usar _declspec(dllimport) para importar de 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), dada a este código:

int main(void) 
{
   func1();
}

o compilador gera código parecido com este:

call func1

e o vinculador traduz a chamada em algo assim:

call 0x4000000         ; The address of 'func1'.

Se func1 existe na DLL de outro, o vinculador não pode resolver nesse diretamente porque ele não tem como saber qual o endereço de func1 Salomão Em ambientes de 16 bits, o vinculador adiciona esse endereço de código para uma lista no arquivo. exe que o carregador seria 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 dos quais ele sabe 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 de importação 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 maior (nos sistemas RISC, ele pode ter várias instruções) e pode prejudicar o desempenho do seu cache. Se você instrui o compilador que a função está em uma DLL, ela 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 as instruções, portanto o código é menor e mais rápido.

Por outro lado, para chamadas de função dentro de uma DLL, você não deseja ter que 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 a partir de fora da própria DLL. Não use __declspec(dllimport) nas funções dentro de uma DLL durante a criação dessa DLL.

Consulte também

Conceitos

Importar para um aplicativo