Qu'est-ce que __declspec et quand dois-je l'utiliser?

157

J'ai vu des exemples de __declspecdans le code que je lis. Qu'Est-ce que c'est? Et quand aurais-je besoin d'utiliser cette construction?

Scott J
la source
1
Si vous n'aviez pas de chance et que vous passiez de Linux à Windows, vous pourriez perdre du temps à essayer de comprendre pourquoi vos DLL ne fonctionneraient pas, jusqu'à ce que vous constatiez que vous devez ajouter __declspec(dllexport)avant chaque fonction de votre bibliothèque
SomethingSomething

Réponses:

74

Il s'agit d'une extension spécifique à Microsoft du langage C ++ qui vous permet d'attribuer un type ou une fonction avec des informations de classe de stockage.

Documentation

__declspec (C ++)

JaredPar
la source
19
Merci - mais à quoi l'utilisais-je?
Scott J
4
Pour déclarer des interfaces et des classes COM, par exemple, vous utilisez __declspec (uuid), pour exporter des fonctions sans fichier DEF, vous utilisez __declspec (dllexport), etc. La liste complète est assez longue.
Seva Alekseyev
1
@ScottJ Je l'utilise constamment pour les propriétés: __declspec (property (get = X put = X)) identifiant de type de données. MSDN a bien sûr plus de détails. En tant que "programmeur C # vers C / C ++", c'est un bonheur!
MasterMastic
51

Les exemples canoniques sont __declspec(dllimport)et __declspec(dllexport), qui indiquent à l'éditeur de liens d'importer et d'exporter (respectivement) un symbole depuis ou vers une DLL.

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


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

( __declspec(..)résume simplement les éléments spécifiques de Microsoft - pour assurer la compatibilité, on les emballerait généralement avec des macros)

Alexander Gessler
la source
8
@tetris, vous ne savez pas d'après le code. La décision est prise par l'éditeur de liens, qui choisira le premier .libqu'il trouve qui a un symbole exporté correspondant.
Euro Micelli
19

Il est principalement utilisé pour importer / exporter des symboles vers une bibliothèque partagée (DLL). Les compilateurs Visual C ++ et GCC prennent en charge __declspec(dllimport)et __declspec(dllexport). D'autres utilisations (certaines uniquement pour Microsoft) sont documentées dans le MSDN .

AndiDog
la source
12

Un autre exemple pour illustrer le __declspec clé :

Lorsque vous écrivez un pilote de noyau Windows, vous souhaitez parfois écrire vos propres séquences de code prologue / épilogue à l' aide du code assembleur en ligne , afin que vous puissiez déclarer votre fonction avec l' attribut nu .

__declspec( naked ) int func( formal_parameters ) {}

Ou

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

Veuillez vous référer à nu (C ++)

HackNone
la source
8

Essentiellement, c'est la façon dont Microsoft introduit ses extensions C ++ afin qu'elles ne soient pas en conflit avec les futures extensions du C ++ standard. Avec __declspec, vous pouvez attribuer une fonction ou une classe; la signification exacte varie selon la nature de __declspec. __declspec (nu), par exemple, supprime la génération de prologue / épilog (pour les gestionnaires d'interruptions, le code intégrable, etc.), __declspec (thread) crée une variable thread-local, et ainsi de suite.

La liste complète des attributs __declspec est disponible sur MSDN et varie selon la version du compilateur et la plate-forme.

Seva Alekseyev
la source
1
Compte tenu des compilateurs non Microsoft comme GCC 4.2, qui offre alternative en plus de leur __attribute__ ((dllexport))à __declspec(dllexport), est - il juste d'appeler __declspec, une extension Microsoft seule?
user2338150
0

Je sais que cela fait huit ans mais je voulais partager ce morceau de code trouvé dans MRuby qui montre comment __declspec()abeille peut être utilisé au même niveau que le 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

la source