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

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

据我了解,调用者和被调用者都需要具有相同的调用约定。否则,堆栈可能已损坏。

WinMain__stdcall 声明并调用我定义的所有函数。这是否意味着我定义的所有函数都应该使用 stdcall 调用约定?

我试过不使用 __stdcall 并且没有发生任何不好的事情。我还看到支持 Windows 的著名 GUI 库不使用 stdcall。为什么堆栈没有损坏?

WinMain is declared with __stdcall and calls all the functions I've defined. Does this mean all the functions I define should use the stdcall calling convention?

没有。调用约定是在每个函数调用的基础上处理的,就在调用站点。该约定规定了调用者和被调用者如何管理调用堆栈——如何传递参数、以什么顺序、谁清理堆栈等。只要调用者和被调用者同意在每个单独的函数调用上使用相同的调用约定, stdcall 函数调用使用不同约定的函数(如 cdecl)是完全安全的,反之亦然。函数的调用约定仅适用于:

  • 新调用者正在输入函数。
  • 函数正在return返回那个调用者。
  • 函数正在访问它自己的参数。

除此之外,函数在内部执行的操作与其自身的调用约定无关。

例如,假设 WinMain(),一个 stdcall 函数,想要调用一个 cdecl 函数。

WinMain() 本身就是一个 stdcall 函数根本不重要。虽然代码执行在 WinMain() 内部,但它可以为所欲为。 WinMain()stdcall 约定仅适用于 WinMain() 本身的进入和退出。那是 WinMain() 与 ITS 来电者的合同。

重要的是WinMain()在为即将调用的cdecl函数设置调用堆栈时必须遵循cdecl的规则,并清理当该函数 return 回到 WinMain().

时调用堆栈

任何调用约定的任何函数调用也是如此。

I've tried not using __stdcall and nothing bad happened. I have also seen well-known GUI libraries supporting Windows don't use stdcall. Why is the stack not corrupting?

因为调用堆栈在每次函数调用时都得到了正确的管理 return,所以没有不平衡的清理破坏堆栈。