3

我正在用 Visual C++ 编译一些第三方 C 代码。源代码树包含以下 .def 文件:

LIBRARY "ThirdParty.dll"

EXPORTS
   ThirdPartyFunction @1

并且在定义附近没有明确的调用约定规范(如__stdcallor __cdeclThirdPartyFunction()。Visual C++ 项目属性(C++ -> 高级 -> 调用约定)设置为__cdecl (/Gd).

导出函数将使用哪个调用约定,我如何确保它是那个约定?

4

1 回答 1

5

A .def file does not control the calling convention, it is purely determined by the compiler. If you don't explicitly use __cdecl or __stdcall in the function declaration then it is the compiler's default, so __cdecl. Corner cases are __thiscall for C++ member functions and __clrcall for managed code.

The calling convention also selects the name decoration style, specifically invented to avoid accidents with client code getting it wrong. __cdecl adds a single underscore before the name, __stdcall appends "@n" where n is the size of the stack activation frame. Which protects against a stack imbalance when the client code uses a wrong declaration with a mismatch in type or number of the arguments, a fatal and very hard to diagnose problem with __stdcall. Disabling this decoration with a .def file is actually a bad idea and should only ever be contemplated if the DLL is dynamically loaded with LoadLibrary+GetProcAddress. If you intend to have your DLL used by non C/C++ clients then it usually a good idea to use __stdcall explicitly since that tends to be the default for other language runtimes.

None of this matters for 64-bit code, it blissfully has only one calling convention. Although it looks like Microsoft is about to mess that up by adding the __vectorcall calling convention.

于 2013-07-18T13:34:13.497 回答