我目前正在为 Windows 开发一个 C++ 库,它将作为 DLL 分发。我的目标是最大化二进制互操作性;更准确地说,我的 DLL 中的函数必须可以从使用多个版本的 MSVC++ 和 MinGW 编译的代码中使用,而无需重新编译 DLL。但是,我很困惑哪种调用约定最好,cdecl
或者stdcall
.
有时我会听到诸如“C 调用约定是唯一保证跨编译器相同的”之类的声明,这与“对 的解释存在一些变化cdecl
,特别是在如何返回值方面”之类的声明形成鲜明对比。这似乎并没有阻止某些库开发人员(如libsndfile)在他们分发的 DLL 中使用 C 调用约定,而没有任何明显的问题。
另一方面,stdcall
调用约定似乎定义明确。据我所知,基本上所有 Windows 编译器都必须遵循它,因为它是用于 Win32 和 COM 的约定。这是基于这样的假设,即不支持 Win32/COM 的 Windows 编译器不会很有用。论坛上发布的许多代码片段都将函数声明为,stdcall
但我似乎无法找到一篇清楚地解释原因的帖子。
那里有太多相互矛盾的信息,我运行的每次搜索都会给我不同的答案,这并不能真正帮助我在两者之间做出决定。我正在寻找一个清晰、详细、有争议的解释,说明为什么我应该选择一个而不是另一个(或者为什么两者是等价的)。
请注意,这个问题不仅适用于“经典”函数,还适用于虚拟成员函数调用,因为大多数客户端代码将通过“接口”与我的 DLL 交互,纯虚拟类(遵循此处和此处描述的模式)。