【问题标题】:Why winmain parameters doesn't match to each other?为什么winmain参数不匹配?
【发布时间】:2016-04-19 08:39:03
【问题描述】:

为什么 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 是空字符串 - 所以它不匹配。为什么?

【问题讨论】:

    标签: visual-studio qt winmain qapplication


    【解决方案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 指向一个连续的字符缓冲区而不是一个字符串数组作为@ 987654335@.

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

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

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

    【讨论】:

    • 你是对的,使用 main() 它可以完美唤醒,但我不需要在开始时使用控制台窗口,所以使用了 winmain。是否可以使用 main() 而不是显示控制台?
    • 然后启动一些小部件窗口。你的确切代码是什么?请参阅 Qt 示例doc.qt.io/qt-5/…
    • 我启动了 QML GUI,但在它加载之前(需要一些时间)控制台窗口会显示出来。
    • 需要您的准确代码。 QML 并不暗示控制台窗口。那是主要功能问题。那里出了点问题。
    【解决方案2】:

    由于这个问题再次与 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 用户存在 afaik,因为使用 mingw 您可以禁用控制台窗口并继续使用 main(),如 Qt 示例中所示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-27
      • 2016-11-23
      • 2014-09-14
      • 2015-05-23
      • 1970-01-01
      • 2011-03-17
      相关资源
      最近更新 更多