为什么winmain参数不相互匹配?

时间:2016-01-14 05:48:14

标签: visual-studio qt winmain qapplication

为什么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为空字符串 - 因此它不匹配。为什么呢?

2 个答案:

答案 0 :(得分:1)

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的字符串数组。

考虑如何在Windows上实现main()函数是有意义的。有一个很好的讨论:WINMAIN and main() in C++ (Extended)请注意,必须在main()函数运行之前初始化C运行时,这可能取决于编译器/链接器。还可以找到Qt application main function的示例。

我认为通过引入nShowCmd == 0使代码不崩溃的情况会使QApplication对象不读取命令行,这会阻止通过{{{}中的地址解释的随机内容的错误访问1}}。但这仍然是错误的,_lpCmdLine对象的初始化不完整。

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

答案 1 :(得分:0)

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

QApplication app(__argc, __argv);

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

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