windows - stdcall 可以有可变参数吗?

标签 windows winapi calling-convention stdcall variadic-functions

据我所知,只有 caller-clean-stack 约定可以使用变量参数。
顺便说一句,WinApi StringCchPrintfW 是这样声明的。(我删除了 SAL)

__inline HRESULT __stdcall
StringCchPrintfW(
STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat, ...
);

stdcall 也可以有可变参数吗?

最佳答案

没有。 stdcall调用约定让被调用者清理堆栈。由于被调用者正在清理堆栈,因此它无法在编译时知道要弹出多少内容,因此它不能具有可变参数。

为了拥有可变数量的函数参数,您需要使用 cdecl ,让调用者清理堆栈。这一切都由编译器确定传递了多少参数,并且由于调用者正在清理堆栈,因此它也知道当函数调用返回时从堆栈中弹出多少参数。

在上面提到的情况下,函数被声明为使用__stdcall,正如前面提到的,它不支持变量参数。在这种情况下,编译器决定忽略定义的调用约定并恢复到 __cdeclstdcall 的描述中提到了此行为。 , 上文提到的。我引用:

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/

相关文章:

python - 当我为 Linux 和 Windows 开发 python 代码时,我需要考虑什么?

security - 如何使用 windows api 用 ssl 透明地包装 tcp/ip 请求

c++ - C++中的子窗口问题

c - x86 与 x86_64 调用约定

javascript - JQuery-热键和windows提示问题

Linux 上运行的 Python Pyro 在远程 windows 机器上打开一个 COM 对象,可能吗?

c++ - Windows 函数 "GetCursorInfo"返回成功但光标的 HANDLE 为 NULL

c - x64 帧指针应该指向哪里,为什么指向? ( Windows x64 ABI)

linux - 从不对齐 RSP 的函数调用时,glibc scanf 出现段错误

java - 使用java.exe时出错