Eu vi o código-fonte do Qt assim:
class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};
Qual Q_CORE_EXPORT
macro define como abaixo:
define Q_DECL_IMPORT __declspec(dllimport)
Então, o que __declspec(dllimport)
realmente significa?
Eu vi o código-fonte do Qt assim:
class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};
Qual Q_CORE_EXPORT
macro define como abaixo:
define Q_DECL_IMPORT __declspec(dllimport)
Então, o que __declspec(dllimport)
realmente significa?
Respostas:
__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 dllimport
e 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 .DEF
arquivo 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 dllexport
para marcar um símbolo como exportado de uma DLL e dllimport
para 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_EXPORT
macro faz, resolvendo para Q_DECL_IMPORT
ou Q_DECL_EXPORT
.
__declspec
notaçã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.
__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)
.
__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
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.