这个 WinMain() 声明中发生了啥?

Posted

技术标签:

【中文标题】这个 WinMain() 声明中发生了啥?【英文标题】:What is happening in this WinMain() declaration?这个 WinMain() 声明中发生了什么? 【发布时间】:2012-02-04 20:52:32 【问题描述】:

我正在学习 C++ 和 windows api 编程。我的第一个“Hello Windows API”程序只显示一个 MessageBox()。但是,我有一些我正在阅读的书没有解释的问题。

首先,程序如下:

// HelloWin32 Program
#include<Windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)

    MessageBox(NULL, "This gets displayed in the message.", "This is the title bar of the message dialog.", MB_OK | MB_ICONEXCLAMATION);

这编译并运行良好。我的问题与 int WINAPI WinMain(...) 的 WinMain() 声明有关。当我读到它时,WinMain 函数(方法?)返回一个整数。但是WINAPI 传达了什么信息?

显然,我正在写 Windows API。 WINAPI 是否以某种方式标记该函数,以便程序使用 Windows API 执行它或其他什么?

【问题讨论】:

【参考方案1】:

WINAPI 是一个预处理器定义,定义为__stdcall,一个调用约定;当函数的名称前有__stdcall 时,这是编译器的指令,使函数使用该调用约定。这样你的函数和调用你的函数的函数都同意使用 stdcall 调用约定并且调用正确执行。

这是必要的,因为您的编译器的默认调用约定可能是也可能不是 stdcall,因此您必须明确告诉编译器为该函数采用这种方式。 Windows API 的设计者决定,主要是出于兼容性原因和 stdcall 调用约定的普遍性,让所有函数调用都使用 stdcall 调用约定。

此外,您可以在同一程序中使用具有不同调用约定的函数。因此,例如,WinMain 必须是 stdcall 但程序的其他函数不是;他们可以使用编译器默认值。

调用约定是一种方法,用于执行诸如参数进入堆栈的顺序、函数返回时谁应该从堆栈中删除它们、将返回值放在哪里以及其他事情。不同的调用约定以不同的方式执行此操作。最重要的是,调用者和被调用者都遵循相同的调用约定,这一点非常重要。有关调用约定的更多信息,请参阅the Wikipedia article。

【讨论】:

了解不同的调用约定对我来说重要吗?我以前从未遇到过它们(我从 C# 开始。) @quakkels 非常好,但并非绝对有必要知道。如果您曾经深入研究生成的 C++ 程序程序集,则有必要了解调用约定,否则可以将其视为实现细节(隐藏在 WINAPI 预处理器定义后面)。可能(尽管我没有证据)许多 C++ 程序员编写了很好的程序,但对调用约定一无所知。了解更多关于底层如何运作的信息从来都不是一件坏事:)

以上是关于这个 WinMain() 声明中发生了啥?的主要内容,如果未能解决你的问题,请参考以下文章

当我们声明静态变量时,编译器实际上做了啥?

UIMenuController 和响应者链:发生了啥?

“()”在等级声明中做了啥

C++11 中的“转换构造函数”发生了啥变化? [复制]

关于VC++的Winmain函数(WINAPI是啥?)

在这个简单的函数调用堆栈中发生了啥?