stdcall 可以有可变参数吗? [英] Can stdcall have a variable arguments?

查看:34
本文介绍了stdcall 可以有可变参数吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

As far as I know, only the caller-clean-stack convention can use variable arguments.
By the way, the WinApi StringCchPrintfW is declared like this.(I removed the SAL)

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

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

stdcall 也可以有可变参数吗?

Can stdcall have a variable arguments either?

推荐答案

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

No. The stdcall calling convention has the callee clean the stack. Since the callee is cleaning the stack there is no way for it to know at compile time how much to pop off, therefore it cannot have variable arguments.

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

In order to have variable number of function arguments you need to use cdecl, which has the caller clean the stack. This all the compiler to determine how many arguments are being passed and since the caller is cleaning up the stack it also knows how much to pop off the stack when the call to the function returns.

在上面提到的情况下,函数被声明为使用 __stdcall,如前所述,它不支持变量参数.在这种情况下,编译器决定忽略定义的调用约定并恢复到 __cdecl.stdcall,上面提到过.我引用:

In the case mentioned above, the function is declared to use __stdcall, which as previously mentioned does not support variable arguments. In this case, the compiler makes the decision to ignore the calling convention defined and revert back to __cdecl. This behavior is alluded to in the description for stdcall, mentioned above. I quote:

被调用者清理堆栈,所以编译器生成 vararg 函数__cdecl.

The callee cleans the stack, so the compiler makes vararg functions __cdecl.

如果编译以下代码并反汇编对函数的调用,则可以观察到这一点.

This can be observed if the following code is compiled and a call to the function disassembled.

int __stdcall Bar(int a, int b, ...)
{
  return b * a;
}

结果代码将被视为__cdecl.至于这样定义的原因,我不知道.

The resulting code will be treated as __cdecl. As to the reason this is defined that way, I do not know.

这篇关于stdcall 可以有可变参数吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆