据我所知,只有 caller-clean-stack 约定可以使用变量参数。
顺便说一句,WinApi StringCchPrintfW 是这样声明的。(我删除了 SAL)
__inline HRESULT __stdcall
StringCchPrintfW(
STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat, ...
);
stdcall 也可以有可变参数吗?
最佳答案
没有。 stdcall调用约定让被调用者清理堆栈。由于被调用者正在清理堆栈,因此它无法在编译时知道要弹出多少内容,因此它不能具有可变参数。
为了拥有可变数量的函数参数,您需要使用 cdecl ,让调用者清理堆栈。这一切都由编译器确定传递了多少参数,并且由于调用者正在清理堆栈,因此它也知道当函数调用返回时从堆栈中弹出多少参数。
在上面提到的情况下,函数被声明为使用__stdcall
,正如前面提到的,它不支持变量参数。在这种情况下,编译器决定忽略定义的调用约定并恢复到 __cdecl
。 stdcall 的描述中提到了此行为。 , 上文提到的。我引用:
The callee cleans the stack, so the compiler makes vararg functions __cdecl.
如果编译以下代码并反汇编对函数的调用,则可以观察到这一点。
int __stdcall Bar(int a, int b, ...)
{
return b * a;
}
生成的代码将被视为__cdecl
。至于这样定义的原因,我不知道。
关于windows - stdcall 可以有可变参数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3615402/