【问题标题】:How it is possible to have entry point other than main(), in Win32 projects in C++. (WinMain)在 C++ 的 Win32 项目中,如何拥有除 main() 之外的入口点。 (WinMain)
【发布时间】:2018-02-17 22:44:57
【问题描述】:

从我读过的关于 C 和 C++ 的书籍中,我了解到 C 程序的入口点必须是 main。直到现在我只制作了控制台应用程序,现在我开始学习 Windows 应用程序。所以我的问题是:

为什么 Win32 项目中的入口点不是 main(而是 WinMain),怎么可能不同(也许 main 调用 WinMain?)?

ps。抱歉英语不好

【问题讨论】:

标签: c++


【解决方案1】:

C++ 确实需要main 作为程序的“入口点”,至少在所谓的“托管实现”(您可能正在使用的实现)下是这样。这就是为什么如果您忘记定义 main 会在 GCC 中出现链接器错误的原因。

然而,在实践中,你的程序结束和“运行时”开始之间的差距,让事情看起来有点毛骨悚然——当你的程序启动时,第一个调用的函数实际上是在运行时内部,最终会绕过调用main。如果您忘记定义main,实际上正是此调用导致链接器错误。

Microsoft 已决定,对于 Windows GUI 程序,它们的运行时将调用 WinMain,而不是调用 main。因此,您必须为它定义一个函数WinMain,而不是main。从技术上讲,这违反了 C++ 标准,但它之所以有效,是因为 Microsoft 让它有效。

【讨论】:

  • 这不仅仅是一个约定。这是使用 MS 链接器编译并使用 MS 运行时的程序的要求。
  • Windows GUI 程序无论如何都是不可移植的,因此微软为它们提供非标准入口点这一事实并不是什么大问题......我认为......
  • @bolov:我同意。
  • @SebastianRedl:这不是我说的吗?
  • @LightnessRacesinOrbit 我正在回复一条现已删除的评论。
【解决方案2】:

代码中入口点的实际名称和签名由您决定在 EXE 中使用的运行时框架决定。

操作系统在执行EXE时,首先调用链接器在EXE头中指定的入口点,通常位于编译器厂商的运行时库中。

运行时库的入口点初始化库,设置全局变量等,然后最后调用您的代码必须实现的入口点(运行时库包含对外部入口点的引用,链接器连接您代码的该引用的入口点)。

因此,您的代码的入口点是运行时库所要求的。 C/C++ 中控制台应用程序的标准 入口点是main,Windows GUI 应用程序的传统 入口点是WinMain。但就操作系统而言,这不是要求。

【讨论】:

    【解决方案3】:

    实际上main 只是汇编语言的一个名称:您可以随意声明您的Entry Point,例如:

    .code
    
    START:
    ret
    END START
    

    但在 C++ 中,它不允许您定义自己的 EP。所以必须实现约定:对于控制台,您需要 main、wmain、win32:WinMain,对于 Dll:dllmain...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-31
      • 2012-12-02
      • 1970-01-01
      • 2010-09-29
      • 1970-01-01
      • 1970-01-01
      • 2013-09-13
      相关资源
      最近更新 更多