据我所知,只有调用方清洁堆栈约定才能使用可变参数。
顺便说一句,WinApi StringCchPrintfW是这样声明的。(我删除了SAL)
__inline HRESULT __stdcall StringCchPrintfW( STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat, );
stdcall也可以有变量参数吗?
发布于 2010-09-01 06:03:51
不是的。stdcall调用约定让被调用者清理堆栈。由于被调用方正在清理堆栈,因此无法在编译时知道要弹出多少参数,因此不能使用变量参数。
为了拥有可变数量的函数参数,您需要使用cdecl,它让调用方清理堆栈。这是所有编译器用来确定传递了多少参数的编译器,而且由于调用方正在清理堆栈,所以当函数调用返回时,它还知道要弹出多少参数。
在上面提到的情况下,函数被声明为使用__stdcall,正如前面提到的,它不支持变量参数。在这种情况下,编译器决定忽略已定义的调用约定并返回到__cdecl。上述对stdcall的描述中提到了这种行为。我引述如下:
被调用者清理堆栈,因此编译器使vararg函数__cdecl。
如果编译了以下代码并解压缩了对该函数的调用,则可以观察到这一点。
int __stdcall Bar(int a, int b, ...)
{
return b * a;
}生成的代码将被视为__cdecl。至于原因,这是这样定义的,我不知道。
https://stackoverflow.com/questions/3615402
复制相似问题