__cdecl和__declspec调用约定混淆

Per*_*etz 7 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);
....
....
Run Code Online (Sandbox Code Playgroud)

我有点困惑.为什么使用__declspec约定而不是__cdedl导出函数?__declspec支持_cdecl吗?

谢谢.

AAT*_*AAT 14

__declspec()并且__cdecl正在解决调用函数的两个不同方面,你可以(并且在这种情况下,你应该使用它的声音)使用两者.

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

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

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


mwi*_*ahl 8

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

有关详细信息,__declspec这里.

__cdecl调用约定表示该函数使用传统的"C"语言的参数传递约定.还有其他风格,特别是__stdcall.

关于__cdeclvs __stdcall(和其他)的更多细节在这里.