Was ist __declspec und wann muss ich es verwenden?

157

Ich habe Instanzen __declspecin dem Code gesehen, den ich lese. Was ist es? Und wann müsste ich dieses Konstrukt verwenden?

Scott J.
quelle
1
Wenn Sie Pech hatten und von Linux zu Windows gewechselt sind, verschwenden Sie möglicherweise Zeit damit, herauszufinden, warum Ihre DLLs nicht funktionieren, bis Sie feststellen, dass Sie __declspec(dllexport)vor jeder Funktion in Ihrer Bibliothek
etwas

Antworten:

74

Dies ist eine Microsoft-spezifische Erweiterung der C ++ - Sprache, mit der Sie einen Typ oder eine Funktion mit Speicherklasseninformationen zuordnen können.

Dokumentation

__declspec (C ++)

JaredPar
quelle
19
Danke - aber wofür würde ich es verwenden?
Scott J
4
Zum Deklarieren von COM-Schnittstellen und -Klassen verwenden Sie beispielsweise __declspec (uuid), zum Exportieren von Funktionen ohne DEF-Datei __declspec (dllexport) usw. Die vollständige Liste ist ziemlich lang.
Seva Alekseyev
1
@ScottJ Ich benutze es ständig für Eigenschaften: __declspec (Eigenschaft (get = X put = X)) Datentyp-ID. MSDN hat natürlich mehr Details. Als "C # to C / C ++ - Programmierer" ist es ein Glück!
MasterMastic
51

Die kanonischen Beispiele sind __declspec(dllimport)und __declspec(dllexport), die den Linker anweisen, ein Symbol von oder in eine DLL zu importieren bzw. zu exportieren.

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


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

( __declspec(..)Fasst nur die spezifischen Inhalte von Microsoft zusammen. Um Kompatibilität zu erreichen, werden normalerweise Makros verwendet.)

Alexander Gessler
quelle
8
@tetris, du weißt es nicht aus dem Code. Die Entscheidung trifft der Linker, der den ersten auswählt, der .libein passendes exportiertes Symbol enthält.
Euro Micelli
19

Es wird hauptsächlich zum Importieren von Symbolen aus / Exportieren von Symbolen in eine gemeinsam genutzte Bibliothek (DLL) verwendet. Sowohl Visual C ++ - als auch GCC-Compiler unterstützen __declspec(dllimport)und __declspec(dllexport). Andere Verwendungen (einige nur von Microsoft) sind im MSDN dokumentiert .

AndiDog
quelle
12

Ein weiteres Beispiel zur Veranschaulichung der __declspec Schlüsselworts :

Wenn Sie einen Windows-Kerneltreiber schreiben, möchten Sie manchmal Ihre eigenen Prolog- / Epilog-Codesequenzen mit Inline-Assembler-Code schreiben , damit Sie Ihre Funktion mit dem nackten Attribut deklarieren können .

__declspec( naked ) int func( formal_parameters ) {}

Oder

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

Bitte beziehen Sie sich auf nackt (C ++)

HackNone
quelle
8

Im Wesentlichen führt Microsoft seine C ++ - Erweiterungen so ein, dass sie nicht mit zukünftigen Erweiterungen von Standard-C ++ in Konflikt stehen. Mit __declspec können Sie eine Funktion oder Klasse zuordnen. Die genaue Bedeutung hängt von der Art der __declspec ab. __declspec (nackt) unterdrückt beispielsweise die Prolog- / Epilog-Generierung (für Interrupt-Handler, einbettbaren Code usw.), __declspec (Thread) erstellt eine Variable threadlokal und so weiter.

Die vollständige Liste der __declspec-Attribute ist auf MSDN verfügbar und variiert je nach Compilerversion und Plattform.

Seva Alekseyev
quelle
1
Unter Berücksichtigung nicht-Microsoft - Compiler wie GCC 4.2, dieses Angebot Alternative neben ihre __attribute__ ((dllexport))zu __declspec(dllexport), ist es fair zu Anruf __declspec, eine Microsoft-only - Erweiterung?
user2338150
0

Ich weiß, dass es acht Jahre her sind, aber ich wollte diesen in MRuby gefundenen Code teilen, der zeigt, wie __declspec()man auf der gleichen Ebene wie der verwendet werden kann 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

quelle