这个 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() 声明中发生了啥?的主要内容,如果未能解决你的问题,请参考以下文章