为什么 _UNICODE 定义时 __tmainCRTStartup 调用 WinMain?

发布于 2024-11-02 12:16:16 字数 400 浏览 0 评论 0原文

你现在就可以尝试这个。

定义 WinMain 和 wWinMain abd 将其编译为静态库。

为可执行文件exe创建一个新项目。

设置字符集设置UNICODE系统。(define _UNICODE)

链接刚才制作的静态库。

然后你的程序从WinMain启动。

无论字符集是多字节还是unicode,当WinMain 和wWinMain 都被定义时,WinMain 都会被调用。

仅当您在静态库中定义 WinMain 时才会发生这种情况。

当您在源项目中定义 WinMain 和 wWinMain 时,它可以正常工作,包括

unicode 系统调用 wWinMain 和多字节系统调用 WinMain。

为什么会发生这种情况?

You can try this right now.

Define both WinMain and wWinMain abd compile it as a static library.

Make a new project for executable file exe.

Set character set setting UNICODE system.(define _UNICODE)

Link the static library just made.

Then your program starts from WinMain.

Whether the character set is multi-byte or unicode, WinMain is called, when both WinMain and wWinMain is defined.

It happens only when you define WinMain in a static library.

When you define WinMain and wWinMain in a source project including, it works correctly,

unicode system calls wWinMain and multi-byte system calls WinMain.

Why does it happen?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

黄昏下泛黄的笔记 2024-11-09 12:16:16

链接器尝试推断您的入口点是什么并替换 __tmainCRTStartup 的相应实现。然而,这里有两个限制:

  • 链接器的设计目的不是在两个或多个入口点之间进行猜测。事实上,当链接器发现超过一个选择。
  • 链接器不知道预处理器,因此您定义的任何预处理器符号在链接器运行时都是无关紧要的。

因此,要回答你为什么看到这个问题,你是否遇到了“未定义行为”的情况之一。您不应依赖此行为,因为它不能保证正常工作,并且可能会在新的编译器版本中发生变化。

我建议您使用 _tWinMain 定义一个单一入口点:

int APIENTRY _tWinMain(HINSTANCE hInstance,   
                 HINSTANCE hPrevInstance,   
                 LPTSTR    lpCmdLine,   
                 int       nCmdShow)   

链接器还有 /ENTRY 选项,但我不建议您使用它,因为它更危险,您可以通过简单地定义单一入口函数并传递来完成相同的功能/SUBSYSTEM 链接器选项的正确值。

Linker tries to deduce the what your entry point is and substitute correspoinding implementation of __tmainCRTStartup. However there are two limitations here:

  • Linker was not designed to make a guess between two or more entry points. In fact linker produces warning LNK4067: ambiguous entry point when it finds more than one choice.
  • Linker does not know about preprocessor, so whatever preprocessor symbols you defined are irrelevant at the time linker runs.

So, to answer your question why you see this, is you are hitting one of the cases of "undefined behavior". You should not rely on this behavior because it is not guaranteed to work and might change in new compiler version.

I suggest you define one single entry point using _tWinMain:

int APIENTRY _tWinMain(HINSTANCE hInstance,   
                 HINSTANCE hPrevInstance,   
                 LPTSTR    lpCmdLine,   
                 int       nCmdShow)   

There is also /ENTRY option for linker, but I don't recommend you using it, because it is more dangerous and you can accomplish the same functionality by simply defining single entry function and passing correct value for the /SUBSYSTEM linker option.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文