我正在用Visual C++编译一些第三方C代码。源树包含以下.def文件:
LIBRARY "ThirdParty.dll"
EXPORTS
ThirdPartyFunction @1而且在ThirdPartyFunction()定义附近没有明确的调用约定规范(如__stdcall或__cdecl)。可视C++项目属性(C++ ->高级->调用约定)设置为__cdecl (/Gd)。
哪个调用约定将用于导出的函数,我如何确保它是该约定?
发布于 2013-07-18 21:34:13
.def文件并不控制调用约定,它完全由编译器决定。如果您没有在函数声明中显式地使用__cdecl或__stdcall,那么它就是编译器的默认值,所以使用__cdecl。角例是用于C++成员函数的__thiscall和用于托管代码的__clrcall。
调用约定还选择了名称修饰样式,这是专门为避免客户端代码出错而发明的。__cdecl在名称前添加一个下划线,__stdcall附加"@n“,其中n是堆栈激活帧的大小。当客户端代码使用类型或参数数量不匹配的错误声明时,它可以防止堆栈不平衡,这是一个致命的、非常难以诊断的__stdcall问题。使用DLL文件禁用此修饰实际上不是一个好主意,只有在使用LoadLibrary+GetProcAddress动态加载.def时才应该考虑这样做。如果您打算让非C/C++客户端使用您的DLL,那么显式使用__stdcall通常是一个好主意,因为这往往是其他语言运行时的默认设置。
对于64位代码来说,这些都无关紧要,因为它只有一个调用约定。尽管看起来微软通过添加__vectorcall调用约定来实现about to mess that up。
https://stackoverflow.com/questions/17722817
复制相似问题