为什么 winmain 参数彼此不匹配?

Why winmain parameters doesn't match to each other?

为什么 QApp 构造函数因 WinMain 个参数而失败?

 int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPTSTR _lpCmdLine, int _nShowCmd) {
    QApplication app(_nShowCmd, & _lpCmdLine);

这里失败并出现异常:

Exception at adress 0x0F3621DC (Qt5Guid.dll) in updater_app.exe: 0xC0000005

怎么了?如何解决?

UPD:

它的工作方式是这样的:

int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPTSTR _lpCmdLine, int _nShowCmd) {

int nShowCmd(0);
QApplication app(nShowCmd, & _lpCmdLine);

_lpCmdLine 是 10 而 _nShowCmd 是空字符串 - 所以它不匹配。为什么?

Qt 应用程序 QApplication 主对象应该在标准主函数中创建:

int main(int argc, char *argv[])
{
   QApplication app(argc, argv);
   // more app objects initialization
   return app.exec();
}

而你:

int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPTSTR _lpCmdLine, int _nShowCmd)
{
   QApplication app(nShowCmd, & _lpCmdLine);
   return app.exec();
}

这意味着 &_lpCdLine 等同于 argv 但是:

LPTSTR _lpCmdLine 等同于 char* 并且您获取它的地址,因此 &_lpCmdLine 匹配 char**_lpCmdLine 指向连续的字符缓冲区而不是字符串数组 argv.

考虑 main() 函数是如何在 Windows 上实现的是有意义的。有一个很好的讨论:WINMAIN and main() in C++ (Extended) Mind that the C runtime must be initialized before main() function runs and that may depend on compiler/linker. And also find an example of Qt application main function.

我想当你通过引入 nShowCmd == 0 让你的代码不崩溃时,QApplication 对象不会读取命令行,这可以防止通过解释为地址的随机内容进行不正确的访问_lpCmdLine。但这仍然是错误的,并且 QApplication 对象的初始化不完整。

作者没有看到 window 而是看到了控制台,这与不启动任何 window 的主要功能代码不完整有关。此外,QML application main.cpp 可能会有所帮助。

由于这个问题再次与 Qt6 相关,这里有一个非常简单的 VisualStudio 解决方案,使用 WinMain 作为入口点:

QApplication app(__argc, __argv);

__argc 和 __argv 由 Microsoft 编译器填充 (在这里找到这个建议:https://codingmisadventures.wordpress.com/2009/03/10/retrieving-command-line-parameters-from-winmain-in-win32/

问题的简短说明:将 main() 与 VC 一起使用需要使用 Subsystem:Console,但这总是会打开一个控制台 window,您通常希望避免这种情况。你无法摆脱这个控制台,除非使用一些非常肮脏的技巧。因此,您需要切换到 Subsystem:Windows 才能启动“静默”应用程序,但这需要使用 WinMain() 作为应用程序入口点。在 Qt5 之前,qtmain.lib 中有一个自己的 WinMain() 实现,您只需将其链接进去,然后转发到 main() 函数,但这在 Qt6 中已被踢出。该问题只存在于 MSVC 用户,因为使用 mingw 您可以禁用控制台 window 并继续使用 main(),如 Qt 示例中所示。