o que __declspec (dllimport) realmente significa?

Respostas:

118

__declspecé um atributo específico da Microsoft que permite especificar informações de classe de armazenamento.
(Nitpicker's Corner: No entanto, vários outros fornecedores de compiladores - por exemplo, GCC - agora oferecem suporte a esta extensão de linguagem para compatibilidade com a base instalada de código que foi escrito visando os compiladores da Microsoft. Alguns até fornecem atributos adicionais de classe de armazenamento.)

Dois desses atributos de classe de armazenamento que podem ser especificados são dllimporte dllexport. Eles indicam ao compilador que uma função ou objeto é importado ou exportado (respectivamente) de uma DLL.

Mais especificamente, eles definem a interface da DLL para o cliente sem exigir um .DEFarquivo de definição de módulo ( ). A maioria das pessoas acha muito mais fácil usar essas extensões de linguagem do que criar arquivos DEF.

Por razões óbvias, __declspec(dllimport)e __declspec(dllexport)geralmente são emparelhados. Você usa dllexportpara marcar um símbolo como exportado de uma DLL e dllimportpara importar esse símbolo exportado em outro arquivo.

Por causa disso, e porque o mesmo arquivo de cabeçalho é geralmente usado ao compilar a DLL e no código do cliente que consome a interface da DLL, é um padrão comum definir uma macro que automaticamente resolve para o especificador de atributo apropriado no tempo de compilação. Por exemplo:

#if COMPILING_DLL
    #define DLLEXPORT __declspec(dllexport)
#else
    #define DLLEXPORT __declspec(dllimport)
#endif

E então marcando todos os símbolos que devem ser exportados com DLLEXPORT.

Presumivelmente, é isso que a Q_CORE_EXPORTmacro faz, resolvendo para Q_DECL_IMPORTou Q_DECL_EXPORT.

Cody Gray
fonte
__declspec não é propriamente "específico do MS" (é muito mais "específico do compilador) e alguns compiladores usam essa declaração para plataformas múltiplas também. Alguns dos valores dos atributos são (dllexport / dllimports são específicos do MS, na verdade, uma vez que o DLL é MS léxico).
Emilio Garavaglia
9
@Emilio: Pelo que eu sei, a Microsoft inventou a __declspecnotação como uma extensão da linguagem C ++. Acredito que o GCC agora o suporte, mas isso é principalmente por razões de compatibilidade com os compiladores da Microsoft. E eu não entendo como "específico do MS" é diferente de "específico do compilador". A Microsoft escreveu um compilador C ++ e muitas pessoas o usam. Ele vem com o Visual Studio.
Cody Gray
8
A Microsoft faz um compilador. É chamado de "Microsoft C / C ++ Optimizing Compiler", cl.exe. Muitas pessoas se referem erroneamente ao Visual Studio como se fosse um compilador, mas é um IDE. Eu não sei por que as pessoas são minuciosas sobre o que significa "específico da Microsoft". Isso não significa um "ambiente MS" (seja lá o que for) e certamente não significa "Windows". Sim, outros fornecedores de compiladores agora oferecem suporte à extensão para compatibilidade com a base instalada de código escrito visando aos compiladores da Microsoft. Como eu disse antes, pelo que sei, a Microsoft inventou a sintaxe. Esse é o ponto aqui exposto.
Cody Gray
2
@CodyGray: A Microsoft ter inventado isso sozinha não seria suficiente. No entanto, a Microsoft o inventou, nenhum padrão o continha, outros apenas o implementaram para compatibilidade e ele foi usado principalmente (se não exclusivamente) para programas voltados para o Microsoft Windows juntos, fazem um ponto muito forte para chamá-lo de "específico da Microsoft"
celtschk
6
Esta é uma resposta incrível, especialmente a parte sobre "porque o mesmo arquivo de cabeçalho é geralmente usado tanto ao compilar a DLL quanto no código do cliente"! Torna todos os aspectos de importação / exportação claros.
Ela782 de
30

__declspec(dllimport) é um especificador de classe de armazenamento que informa ao compilador que uma função ou objeto ou tipo de dados está definido em uma DLL externa.

A função ou objeto ou tipo de dados é exportado de uma DLL com um correspondente __declspec(dllexport).

arx
fonte
6
Está bem. Finalmente, após 2 horas de leitura, achei a declaração mais satisfatória, mais concisa e precisa do que eu quero.
el psy Congroo
1

__declspec(dllexport)diz ao compilador para informar ao vinculador que esses símbolos precisam ser colocados na tabela de exportação (ao compilar o .dll). Ao compilar o programa que se vincula com o .dll, __declspec(dllimport)diz ao compilador para produzir uma chamada indireta indireta absoluta relativa a rip (que o linker preencherá para apontar para a tabela de importação) em vez do registro direto relativo a rip usualinstrução de chamada indireta para uma função indefinida (que, como não pode modificar a instrução, o vinculador insere o endereço relativo de uma conversão e, em seguida, cria a conversão, dentro da qual ele coloca a chamada indireta indireta do registro absoluto relativo de rip para o ponteiro de função na tabela de importação). Este é um tamanho de código e otimização de velocidade. É a biblioteca de importação .lib que informa ao vinculador quais símbolos serão importados e é usada como um guia para criar a tabela de importação e criar qualquer thunks necessário no segmento .text.

https://docs.microsoft.com/en-us/cpp/build/importing-function-calls-using-declspec-dllimport?view=vs-2019 https://docs.microsoft.com/en-us/cpp / build / importing-data-using-declspec-dllimport? view = vs-2019 https://stackoverflow.com/a/4490536/7194773

Lewis Kelsey
fonte
-2

Isso significa que a definição da função está em uma biblioteca dinâmica. Consulte a documentação para obter mais detalhes e exemplos.

Armen Tsirunyan
fonte