__cdecl和__declspec调用约定混淆

时间:2011-08-02 16:06:22

标签: c++ c dllimport calling-convention

我正在为第三方应用程序编写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 个答案:

答案 0 :(得分:14)

__declspec()__cdecl正在解决调用函数的两个不同方面,你可以(并且在这种情况下通过它的声音)来使用它们。

__cdecl指定调用约定,它指定参数如何通过堆栈传递给函数,非常重要的是,之后谁清理堆栈(在__cdecl的情况下,它是整理的来电者。)

__declspec(dllimport/dllexport)用于简化从DLL导出函数定义:您不需要使用它们,但导出函数的其他方法非常笨拙。

明确使用__cdecl而不是执行您所拥有的代码片段,这依赖于编译器选择调用约定,这可能是个好主意。您可以使用我认为的命令行开关来覆盖它,我相信默认值会有所不同,具体取决于您是编译C还是C ++代码,因此更明确(通常)更好。

答案 1 :(得分:8)

这些是正交概念。 __declspec仅表示相关实体的“存储类”。在您正在查看的上下文中,它告诉您是否要指定导入或导出函数(这在处理代码时通常会出现问题,这些代码可以构建为DLL的一部分,也可以直接包含在可执行文件中,具体取决于上下文)。

__declspec的更多信息是here

__cdecl调用约定表明该函数使用传统的“C”语言约定来传递参数。还有其他样式,特别是__stdcall

有关__cdecl vs __stdcall(及其他)的更多详情,请here