O que é o __declspec e quando preciso usá-lo?

157

Eu vi instâncias do __declspeccódigo que estou lendo. O que é isso? E quando eu precisaria usar essa construção?

Scott J
fonte
1
Se você não teve sorte e mudou do Linux para o Windows, pode perder tempo tentando descobrir por que suas DLLs não funcionariam, até descobrir que precisa adicionar __declspec(dllexport)antes de cada função da sua biblioteca
SomethingSomething

Respostas:

74

Essa é uma extensão específica da Microsoft à linguagem C ++ que permite atribuir um tipo ou função às informações da classe de armazenamento.

Documentação

__declspec (C ++)

JaredPar
fonte
19
Obrigado - mas para que eu o usaria?
Scott J
4
Para declarar interfaces e classes COM, por exemplo, use __declspec (uuid), para exportar funções sem um arquivo DEF, use __declspec (dllexport) etc. A lista completa é bastante longa.
Seva Alekseyev
1
@ ScottJ Eu constantemente o uso para propriedades: __declspec (property (get = X put = X)) identificador de tipo de dados. O MSDN tem mais detalhes, é claro. Como "programador de C # para C / C ++", é uma alegria!
MasterMastic
51

Os exemplos canônicos são __declspec(dllimport)e __declspec(dllexport), que instruem o vinculador a importar e exportar (respectivamente) um símbolo de ou para uma DLL.

// header
__declspec(dllimport) void foo();


// code - this calls foo() somewhere in a DLL
foo();

( __declspec(..)apenas encerra as coisas específicas da Microsoft - para obter compatibilidade, normalmente é necessário encerrar com macros)

Alexander Gessler
fonte
8
@ Tetris, você não sabe do código. A decisão é tomada pelo vinculador, que escolherá a primeira .libque encontrar que possui um símbolo exportado correspondente.
Euro Micelli
19

É usado principalmente para importar símbolos de / exportar símbolos para uma biblioteca compartilhada (DLL). Os compiladores Visual C ++ e GCC suportam __declspec(dllimport)e __declspec(dllexport). Outros usos (alguns somente da Microsoft) estão documentados no MSDN .

AndiDog
fonte
12

Outro exemplo para ilustrar a palavra- chave __declspec :

Ao escrever um driver de kernel do Windows, às vezes você deseja gravar suas próprias seqüências de código de prólogo / epilog usando o código montador embutido , para poder declarar sua função com o atributo nu .

__declspec( naked ) int func( formal_parameters ) {}

Ou

#define Naked __declspec( naked )
Naked int func( formal_parameters ) {}

Consulte nu (C ++)

HackNone
fonte
8

Essencialmente, é a maneira como a Microsoft introduz suas extensões C ++ para que não entrem em conflito com futuras extensões do C ++ padrão. Com __declspec, você pode atribuir uma função ou classe; o significado exato varia dependendo da natureza de __declspec. __declspec (naked), por exemplo, suprime a geração de prólogo / epilog (para manipuladores de interrupção, código incorporável etc.), __declspec (thread) torna uma variável local de thread e assim por diante.

A lista completa de atributos __declspec está disponível no MSDN e varia de acordo com a versão e a plataforma do compilador.

Seva Alekseyev
fonte
1
Considerando compiladores não-Microsoft, como GCC 4.2, essa alternativa oferta para além da sua __attribute__ ((dllexport))para __declspec(dllexport), é justo chamada __declspec, a Microsoft só de extensão?
user2338150
0

Eu sei que já faz oito anos, mas eu queria compartilhar esse código encontrado no MRuby que mostra como __declspec()pode ser usado no mesmo nível que o export keyword.

/** Declare a public MRuby API function. */
#if defined(MRB_BUILD_AS_DLL)
#if defined(MRB_CORE) || defined(MRB_LIB)
# define MRB_API __declspec(dllexport)
#else
# define MRB_API __declspec(dllimport)
#endif
#else
# define MRB_API extern
#endif

fonte