据我所知,只有 caller-clean-stack 约定可以使用变量参数。
顺便说一句,WinApi StringCchPrintfW 是这样声明的。(我删除了 SAL)
__内联 HRESULT__stdcall
字符串CchPrintfW(
STRSAFE_LPWSTR pszDest、size_t cchDest、STRSAFE_LPCWSTR pszFormat、...
);
stdcall 也可以有可变参数吗?
No. The stdcall http://msdn.microsoft.com/en-us/library/zxk0tw93(v=VS.71).aspx调用约定让被调用者清理堆栈。由于被调用者正在清理堆栈,因此它无法在编译时知道要弹出多少内容,因此它不能具有可变参数。
为了拥有可变数量的函数参数,您需要使用cdecl http://msdn.microsoft.com/en-us/library/zkwh89ks(VS.71).aspx,让调用者清理堆栈。这一切都由编译器确定传递了多少参数,并且由于调用者正在清理堆栈,因此它也知道当函数调用返回时从堆栈中弹出多少参数。
在上述情况下,该函数被声明为使用__stdcall
,如前所述,它不支持变量参数。在这种情况下,编译器决定忽略定义的调用约定并恢复为__cdecl
。描述中提到了此行为stdcall http://msdn.microsoft.com/en-us/library/zxk0tw93(v=VS.71).aspx, 上文提到的。我引用:
被调用者清理堆栈,因此
编译器使vararg功能__cdecl.
如果编译以下代码并反汇编对该函数的调用,则可以观察到这一点。
int __stdcall Bar(int a, int b, ...)
{
return b * a;
}
生成的代码将被视为__cdecl
。至于reason这是这样定义的,我不知道。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)