__cdecl и __declspec путаница в соглашениях о вызовах - PullRequest
7 голосов
/ 02 августа 2011

Я пишу DLL для стороннего приложения. Главный разработчик программного обеспечения упоминает, что приложение использует соглашение о вызовах __cdecl (/ Gd). Что мне нужно, чтобы убедиться, что я использую это.

Кроме того, третья сторона предоставила мне скелет C ++ DLL, который экспортирует функции следующим образом:

#ifdef _EXPORTING
  #define DECLSPEC    __declspec(dllexport)
#else
   #define DECLSPEC    __declspec(dllimport)
#endif

#ifdef __cplusplus
   extern "C" {  
#endif

DECLSPEC int ICD_Create(char* id);
....
....

Я немного растерялся. Почему функции экспортируются с использованием соглашения __declspec вместо __cdedl ?? __declspec поддерживает _cdecl?

Спасибо.

Ответы [ 2 ]

14 голосов
/ 02 августа 2011

__declspec() и __cdecl обращаются к двум различным аспектам вызова функции, и вы можете (и в этом случае по звукам этого вы должны) использовать оба.

__cdecl определяетсоглашение о вызовах, которое определяет, как параметры передаются в функцию через стек, и, что очень важно, кто впоследствии очищает стек (в случае __cdecl это вызывает вызывающий компонент).

__declspec(dllimport/dllexport) используется для упрощения экспорта определений функций из DLL: вам не нужно их использовать, но другие способы экспорта функций довольно громоздки.

Вероятно, это хорошая идея явно использовать __cdecl вместо того, чтобы делать то, что сделал фрагмент кода, который зависит от компилятора при выборе соглашения о вызовах.Я думаю, вы можете переопределить это с помощью переключателей командной строки, и я считаю, что значение по умолчанию отличается в зависимости от того, компилируете ли вы код на C или C ++, поэтому более явный (как обычно) лучше.

8 голосов
/ 02 августа 2011

Это ортогональные понятия.__declspec просто указывает «класс хранения» рассматриваемой сущности.В контексте, который вы просматриваете, он говорит вам, задаете ли вы функции для импорта или экспорта (обычно это проблема при работе с кодом, который может быть собран как часть DLL или непосредственно включен в исполняемый файл, в зависимости отcontext).

Дополнительная информация о __declspec здесь здесь .

соглашение о вызовах __cdecl указывает, что функция использует традиционное соглашение о языке C для передачипараметры.Существуют и другие стили, в частности __stdcall.

Подробнее о __cdecl против __stdcall (и других) здесь .

...