Что такое __declspec и когда мне нужно его использовать?


157

Я видел случаи __declspecв коде, который я читаю. Что это? И когда мне нужно будет использовать эту конструкцию?


1
Если вам не повезло и вы перешли с Linux на Windows, вы можете потратить время на то, чтобы выяснить, почему ваши библиотеки DLL не будут работать, пока не обнаружите, что вам нужно добавить __declspec(dllexport)перед каждой функцией в вашей библиотеке
SomethingSomething

Ответы:


74

Это специфическое расширение Microsoft для языка C ++, которое позволяет вам приписывать тип или функцию с информацией о классе хранения.

Документация

__declspec (C ++)


19
Спасибо - но для чего я бы его использовал?
Скотт Дж

4
Например, для объявления COM-интерфейсов и классов вы используете __declspec (uuid), для экспорта функций без файла DEF вы используете __declspec (dllexport) и т. Д. Полный список довольно длинный.
Сева Алексеев

1
@ScottJ Я постоянно использую его для свойств: __declspec (property (get = X put = X)) идентификатор типа данных. MSDN имеет более подробную информацию, конечно. Как программист с C # на C / C ++ это блаженство!
MasterMastic

51

Каноническими примерами являются __declspec(dllimport)и __declspec(dllexport), которые инструктируют компоновщик импортировать и экспортировать (соответственно) символ из или в DLL.

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


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

( __declspec(..)просто оборачиваем специфические вещи Microsoft - для достижения совместимости обычно оборачивают это макросами)


8
@tetris, вы не знаете из кода. Решение принимает компоновщик, который выберет первый .libнайденный символ с соответствующим экспортированным символом.
Евро Мицелли

19

Он в основном используется для импорта символов из / экспорта символов в общую библиотеку (DLL). Компиляторы Visual C ++ и GCC поддерживают __declspec(dllimport)и __declspec(dllexport). Другие виды использования (некоторые только для Microsoft) описаны в MSDN .


12

Другой пример, иллюстрирующий ключевое слово __declspec :

Когда вы пишете драйвер ядра Windows, иногда вы хотите написать свои собственные последовательности кода пролога / эпилога, используя встроенный код ассемблера , чтобы вы могли объявить свою функцию с атрибутом naked .

__declspec( naked ) int func( formal_parameters ) {}

Или

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

Пожалуйста, обратитесь к голым (C ++)


8

По сути, именно так Microsoft представляет свои расширения C ++, чтобы они не конфликтовали с будущими расширениями стандарта C ++. С __declspec вы можете приписать функцию или класс; точное значение зависит от характера __declspec. Например, __declspec (naked) подавляет генерацию пролога / эпилога (для обработчиков прерываний, встраиваемого кода и т. д.), __declspec (thread) делает переменную thread-local и т. д.

Полный список атрибутов __declspec доступен на MSDN и зависит от версии компилятора и платформы.


1
Учитывая не-Microsoft компиляторы , как GCC 4.2, что предложение альтернативы в дополнение к их , __attribute__ ((dllexport))чтобы __declspec(dllexport), это справедливо для вызова __declspec, Microsoft только расширение?
user2338150

0

Я знаю, что прошло восемь лет, но я хотел поделиться этим фрагментом кода, найденным в MRuby, который показывает, как его __declspec()можно использовать на том же уровне, что и 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.