stdcall 可以有可变参数吗?
据我所知,只有 caller-clean-stack 约定可以使用变量参数。
顺便说一句,WinApi StringCchPrintfW 是这样声明的。(我删除了 SAL)
__inline HRESULT __stdcall
StringCchPrintfW(
STRSAFE_LPWSTR pszDest、size_t cchDest、STRSAFE_LPCWSTR pszFormat、...
);
stdcall 也可以有可变参数吗?
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, ...
);
Can stdcall have a variable arguments either?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不可以。stdcall 调用约定具有被调用者清理堆栈。由于被调用者正在清理堆栈,因此它无法在编译时知道要弹出多少内容,因此它不能具有可变参数。
为了拥有可变数量的函数参数,您需要使用 cdecl ,让调用者清理堆栈。这一切都由编译器确定传递了多少参数,并且由于调用者正在清理堆栈,因此它也知道当函数调用返回时从堆栈中弹出多少参数。
在上述情况下,函数被声明为使用 __stdcall,正如前面提到的,它不支持变量参数。在这种情况下,编译器决定忽略定义的调用约定并恢复到
__cdecl
。 stdcall,上面提到的。我引用:如果编译以下代码并反汇编对该函数的调用,则可以观察到这一点。
生成的代码将被视为
__cdecl
。至于这样定义的原因,我不知道。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.
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.
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:This can be observed if the following code is compiled and a call to the function disassembled.
The resulting code will be treated as
__cdecl
. As to the reason this is defined that way, I do not know.