Partilhar via


Importação de chamadas de função usando __declspec(dllimport)

O exemplo de código a seguir mostra como usar _declspec(DllImport) 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 esse código:

int main(void) 
{
   func1();
}

o compilador gera código parecido com este:

call func1

e o vinculador converte a telefonar em algo assim:

call 0x4000000         ; The address of 'func1'.

If func1 existe no outro DLL, o vinculador não pode resolver isso diretamente porque ele não tem como saber qual o endereço do func1 é. Em ambientes de 16 bit, o vinculador adiciona esse endereço de código a uma lista no arquivo .exe que o carregador seria patch em time de execução com o endereço correto.Em ambientes de 32 bit e 64 bit, o vinculador gera uma conversão dos quais ele sabe o endereço.Em um ambiente de 32 bit a conversão intermediária é semelhante:

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. Todos os endereços são conhecidos, portanto, para o vinculador.O carregador tem apenas atualizar tabela de endereços de importação do arquivo .exe no time 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, pode ser várias instruções) e podem prejudicar o desempenho do seu cache.Se você solicitar que o compilador a função esteja em uma DLL, ele pode gerar uma telefonar 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

Há nenhuma conversão e nenhum jmp instrução, portanto o código é menor e mais rápido.

Por Outros lado, para chamadas de função dentro de uma DLL, não deve ser necessário usar uma telefonar indireta.Você já sabe o endereço da função.Pois time e espaço são necessárias para carregar e armazenar o endereço da função antes de uma telefonar indireta, uma telefonar direta é sempre mais rápido e menor.Você apenas deseja usar __declspec(DllImport) ao chamar funções DLL de fora a DLL propriamente dito.Não use __declspec(DllImport) nas funções dentro de uma DLL ao criar essa DLL.

Consulte também

Conceitos

Importar para um aplicativo