简体   繁体   English

Windows GUI 应用程序中的每个函数都需要使用 stdcall 吗?

[英]Does every function in a Windows GUI application need to use stdcall?

From what I understand, the caller and the callee both need to have the same calling convention.据我了解,调用者和被调用者都需要具有相同的调用约定。 Otherwise, the stack might be corrupted.否则,堆栈可能已损坏。

WinMain is declared with __stdcall and calls all the functions I've defined. WinMain__stdcall声明并调用我定义的所有函数。 Does this mean all the functions I define should use the stdcall calling convention?这是否意味着我定义的所有函数都应该使用stdcall调用约定?

I've tried not using __stdcall and nothing bad happened.我试过不使用__stdcall并且没有发生任何不好的事情。 I have also seen well-known GUI libraries supporting Windows don't use stdcall .我还看到支持 Windows 的著名 GUI 库不使用stdcall Why is the stack not corrupting?为什么堆栈没有损坏?

WinMain is declared with __stdcall and calls all the functions I've defined. WinMain 用__stdcall声明并调用我定义的所有函数。 Does this mean all the functions I define should use the stdcall calling convention?这是否意味着我定义的所有函数都应该使用stdcall调用约定?

No. Calling conventions are handled on a per-function-call basis, right at the call site.不。调用约定是在每个函数调用的基础上处理的,就在调用站点。 The convention dictates how the caller and callee manage the call stack - how parameters are passed, in what order, who cleans up the stack, etc. As long as the caller and callee agree to use the same calling convention on each individual function call, it is perfectly safe for a stdcall function to call a function that uses a different convention, like cdecl , and vice versa.约定规定了调用者和被调用者如何管理调用堆栈——如何传递参数、以什么顺序、谁清理堆栈等。只要调用者和被调用者同意对每个单独的函数调用使用相同的调用约定, stdcall函数调用使用不同约定的函数(如cdecl是完全安全的,反之亦然。 A function's calling convention applies only when:函数的调用约定仅适用于:

  • the function is being entered by a new caller.新调用者正在输入该函数。
  • the function is returning back to that caller.该函数正在返回给该调用者。
  • the function is accessing its own parameters.该函数正在访问它自己的参数。

Outside of that, what a function does internally has nothing to with its own calling convention.除此之外,函数在内部所做的与它自己的调用约定无关。

For example, lets say that WinMain() , a stdcall function, wants to call a cdecl function.例如,假设WinMain() ,一个stdcall函数,想要调用一个cdecl函数。

It does not matter at all that WinMain() is itself a stdcall function. WinMain()本身是一个stdcall函数,这完全无关紧要。 While code execution is inside of WinMain() , it can do whatever it wants.虽然代码执行在WinMain()内部,但它可以为所欲为。 WinMain() 's stdcall convention is applied only upon entry and exit of WinMain() itself. WinMain()stdcall约定仅适用于WinMain()本身的进入和退出。 That is the contract WinMain() has with ITS caller.这就是WinMain()与 ITS 调用者的契约。

What matters is that WinMain() must follow the rules of cdecl when setting up the call stack for a cdecl function that it is about to call into, and cleaning up the call stack when that function returns back to WinMain() .重要的是WinMain()在为即将调用的cdecl函数设置调用堆栈时必须遵循cdecl的规则,并在该函数返回WinMain()时清理调用堆栈。

The same goes for any function call of any calling convention.这同样适用于任何调用约定的任何函数调用。

I've tried not using __stdcall and nothing bad happened.我试过不使用__stdcall并且没有发生任何不好的事情。 I have also seen well-known GUI libraries supporting Windows don't use stdcall .我还看到支持 Windows 的著名 GUI 库不使用stdcall Why is the stack not corrupting?为什么堆栈没有损坏?

Because the call stack is being managed correctly at every function call and return, so there is no unbalanced cleanup to corrupt the stack.因为在每次函数调用和返回时都正确管理调用堆栈,所以没有不平衡的清理来破坏堆栈。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM