Що таке __declspec і коли мені потрібно його використовувати?


157

Я бачив випадки __declspecв коді, який я читаю. Що це? І коли мені потрібно використовувати цю конструкцію?


1
Якщо вам не пощастило і переїхали з Linux в Windows, ви можете витратити час, намагаючись з'ясувати, чому ваші DLL-файли не працюватимуть, поки ви не виявите, що вам доведеться додавати __declspec(dllexport)перед кожною функцією у вашій бібліотеці
SomethingSomething

Відповіді:


74

Це специфічне для Microsoft розширення до мови C ++, яке дозволяє віднести тип або функцію до інформації про клас зберігання.

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

__declspec (C ++)


19
Дякую - але для чого я би його використав?
Скотт J

4
Наприклад, для оголошення інтерфейсів і класів COM, ви використовуєте __declspec (uuid), для експорту функцій, не використовуючи файл DEF, ви використовуєте __declspec (dllexport) тощо. Повний список досить довгий.
Сева Алексєєва,

1
@ScottJ Я постійно використовую його для властивостей: __declspec (властивість (get = X put = X)) ідентифікатор типу даних. MSDN, звичайно, має більш детальну інформацію. Як програміст "C # to 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який виявить, що має відповідний експортний символ.
Euro Micelli

19

В основному використовується для імпорту символів з / експорту символів до спільної бібліотеки (DLL). І Visual C ++, і компілятори GCC підтримують __declspec(dllimport)та __declspec(dllexport). Інші способи використання (лише для Microsoft) задокументовані в MSDN .


12

Ще один приклад для ілюстрації ключового слова __declspec :

Коли ви пишете драйвер ядра Windows, іноді ви хочете написати власні послідовності коду prolog / epilog, використовуючи вбудований код асемблера , щоб ви могли оголосити свою функцію голим атрибутом.

__declspec( naked ) int func( formal_parameters ) {}

Або

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

Зверніться до голих (C ++)


8

По суті, це те, як Microsoft представляє свої розширення C ++, щоб вони не суперечили майбутнім розширенням стандартного C ++. За допомогою __declspec ви можете віднести функцію або клас; точне значення змінюється залежно від природи __declspec. Наприклад, __declspec (голий) пригнічує генерацію prolog / epilog (для обробників переривань, вбудовуваного коду тощо), __declspec (потік) робить змінну нитку локальною тощо.

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


1
Враховуючи не-Microsoft компілятори , як GCC 4.2, що пропозиція альтернативи на додаток до їх , __attribute__ ((dllexport))щоб __declspec(dllexport), це справедливо для виклику __declspec, Microsoft тільки розширення?
користувач2338150

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.