__cdecl and __declspec calling conventions confusi

2020-07-08 07:54发布

问题:

I am writing a DLL for a third party application. The main software engineer mentions that the application uses the __cdecl (/Gd) calling convention. That I need to make sure that I use that.

Additionally, the third party has provided to me a C++ DLL skeleton which exports the functions as follows:

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

#ifdef __cplusplus
   extern "C" {  
#endif

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

I am kind of confused. Why the functions are being exported using __declspec convention instead of __cdedl?? does __declspec support _cdecl?

Thanks.

回答1:

__declspec() and __cdecl are addressing two different aspects of calling the function, and you can (and in this case by the sounds of it you should) use both.

__cdecl specifies the calling convention, which specifies how parameters are passed to the function via the stack, and, very importantly, who cleans up the stack afterwards (in the case of __cdecl it is the caller who tidies up).

__declspec(dllimport/dllexport) is used to simplify exporting function definitions from a DLL: you don't need to use them, but the other ways of exporting functions are quite klunky.

It is probably a good idea to explicitly use __cdecl rather than doing what the code snippet you have has done, which is rely on the compiler to choose the calling convention. You can override this with command-line switches I think, and I believe the default is different depending on whether you are compiling C or C++ code, so more explicit is (as usual) better.



回答2:

These are orthogonal concepts. __declspec just indicates the "storage class" of the entity in question. In the context you're looking it, it's telling you whether you are specifying functions for import or export (this is usually an issue when working with code that could either be built as part of a DLL or directly included in an executable, depending on context).

More information on __declspec is here.

the __cdecl calling convention indicates that the function uses the traditional "C" language convention for passing parameters. There are other styles, notably __stdcall.

More details on __cdecl vs __stdcall (and others) are here.