Co to jest __declspec i kiedy muszę go używać?

157

Widziałem przypadki __declspecw kodzie, który czytam. Co to jest? Kiedy powinienem użyć tej konstrukcji?

Scott J.
źródło
1
Jeśli miałeś pecha i przeniosłeś się z Linuksa na Windowsa, możesz tracić czas próbując dowiedzieć się, dlaczego twoje biblioteki DLL nie działają, dopóki nie zauważysz, że musisz dodać __declspec(dllexport)przed każdą funkcją w swojej bibliotece
SomethingSomething

Odpowiedzi:

74

Jest to rozszerzenie języka C ++ specyficzne dla firmy Microsoft, które umożliwia przypisanie typu lub funkcji do informacji o klasie pamięci.

Dokumentacja

__declspec (C ++)

JaredPar
źródło
19
Dzięki - ale do czego miałbym to wykorzystać?
Scott J
4
Na przykład do deklarowania interfejsów i klas COM używasz __declspec (uuid), do eksportowania funkcji bez pliku DEF używasz __declspec (dllexport) itd. Pełna lista jest dość długa.
Seva Alekseyev
1
@ScottJ Ciągle używam go do właściwości: __declspec (property (get = X put = X)) identyfikator typu danych. MSDN zawiera oczywiście więcej szczegółów. Jako programista "C # do C / C ++" to prawdziwa rozkosz!
MasterMastic
51

Przykłady kanoniczne to __declspec(dllimport)i __declspec(dllexport), które instruują konsolidator, aby importował i eksportował (odpowiednio) symbol z lub do biblioteki DLL.

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


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

( __declspec(..)po prostu podsumowuje specyficzne rzeczy Microsoftu - aby osiągnąć kompatybilność, zwykle pakuje się to w makra)

Alexander Gessler
źródło
8
@tetris, nie wiesz z kodu. Decyzję podejmuje konsolidator, który wybierze pierwszy .libznaleziony, który ma pasujący wyeksportowany symbol.
Euro Micelli
19

Jest używany głównie do importowania symboli z / eksportowania symboli do biblioteki współdzielonej (DLL). Kompilatory Visual C ++ i GCC obsługują __declspec(dllimport)i __declspec(dllexport). Inne zastosowania (tylko niektóre firmy Microsoft) są udokumentowane w witrynie MSDN .

AndiDog
źródło
12

Kolejny przykład ilustrujący __declspec kluczowe :

Kiedy piszesz sterownik jądra systemu Windows, czasami chcesz napisać własne sekwencje kodu prologu / epilogu przy użyciu wbudowanego kodu asemblera , więc możesz zadeklarować swoją funkcję z atrybutem naked .

__declspec( naked ) int func( formal_parameters ) {}

Lub

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

Proszę odnieść się do nagiego (C ++)

HackNone
źródło
8

Zasadniczo jest to sposób, w jaki Microsoft wprowadza swoje rozszerzenia C ++, aby nie kolidowały z przyszłymi rozszerzeniami standardowego C ++. Dzięki __declspec możesz przypisać funkcję lub klasę; dokładne znaczenie zależy od charakteru __declspec. __declspec (nagi), na przykład, pomija generowanie prologu / epilogu (dla programów obsługi przerwań, kodu możliwego do osadzenia itp.), __declspec (wątek) tworzy zmienną lokalną wątku i tak dalej.

Pełna lista atrybutów __declspec jest dostępna w witrynie MSDN i różni się w zależności od wersji kompilatora i platformy.

Seva Alekseyev
źródło
1
Biorąc pod uwagę, non-microsoft kompilatory takie jak GCC 4.2, które oferują alternatywę oprócz ich __attribute__ ((dllexport))do __declspec(dllexport), jest to fair w stosunku do wywołania __declspec, Microsoft tylko rozszerzenie?
user2338150
0

Wiem, że minęło osiem lat, ale chciałem udostępnić ten fragment kodu znaleziony w MRuby, który pokazuje, jak __declspec()można używać pszczoły na tym samym poziomie co 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

źródło