必须在传递给 C 运行时函数的 QWidget 和无效参数之前构造一个 QApplication

Posted

技术标签:

【中文标题】必须在传递给 C 运行时函数的 QWidget 和无效参数之前构造一个 QApplication【英文标题】:Must construct a QApplication before a QWidget & Invalid parameter passed to C runtime function 【发布时间】:2014-05-22 10:28:36 【问题描述】:

我完成了从 Qt4 到 Qt5 的应用程序的迁移,它可以编译并且一切正常,但它在某个时刻崩溃了。我正在调试它并试图找出原因,但我走到了死胡同:

这是堆栈:

main.cpp 第 373 行:

TouchSwibz w(NULL, NULL, renderMode ? renderMode : AppSettings::RASTERMODE);

当它到达断点并且我试图走得更远时,它会像往常一样崩溃

"此应用程序已请求运行时将其终止 不寻常的方式。”

应用程序输出显示

QWidget: Must construct a QApplication before a QWidget
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.

我认为可能是因为在创建主窗口时正在初始化小部件,但是可以做些什么来解决这个问题?什么是一个好的解决方法?我什至不知道这是否是真正的问题。 我使用 Qt 5.2.1 在 Windows 7 x64 下工作并使用 mingw 4.8 32 位进行编译,该应用程序也是 32 位的。一切都是用相同的工具包编译的。 我不知道我还能提供什么其他有用的信息。我尝试进入 QwtSlider 构造函数,但我不能。

【问题讨论】:

【参考方案1】:

我设法通过在调试模式下编译所有库来解决它,结果发现在发布模式下使用库,而在调试模式下构建应用程序会导致未定义的行为发生。

【讨论】:

恰恰相反,它在调试模式下崩溃并尝试发布,它确实有效。在调试模式下编译库并将应用程序设置为调试模式,问题就消失了 天哪,我真是个菜鸟 这里也一样。不幸的是,您不能在 Windows 中将调试与发布二进制文件混合使用。在 Linux 中,没问题。【参考方案2】:

您很可能拥有QWidget 类型的非本地实例。根据定义,这些将在main 开始执行之前被初始化,所以在QApplication 被构造之前。下面的代码重现了这个问题:

#include <QLabel>
#include <QApplication>

QLabel label("Hello, world!");

int main(int argc, char ** argv)

  QApplication app(argc, argv);
  label.show();
  return app.exec();

解决方法是延迟构造,直到有 QApplication 对象:

#include <QLabel>
#include <QApplication>

// Won't ever be a dangling pointer.
QPointer<QLabel> label;

int main(int argc, char ** argv)

  QApplication app(argc, argv);
  QLabel label_("Hello, world!");
  label.reset(&label_);
  label->show();
  return app.exec();

【讨论】:

【参考方案3】:

我刚刚解决了一个类似的问题,下面是我的详细情况和解决方法:

我使用 VS 和 Qt 插件

Qt 版本是 5.7 64 位(但这并不重要)

我在调试和发布模式下都编译成功;

我可以在调试模式下运行它,但不能在发布模式下运行,这会导致消息“必须在 QWidget 之前构建 QApplication”。

[重要]我首先在 DEBUG 模式下编译和测试它,然后我遇到了一些鼓励我使用 RELEASE 模式的计算阈值。

[重要]我使用了一些第三方库,与 Qt GUI 组件相关,需要您在项目中添加外部依赖项。

[重要]我只是将项目属性页面中的配置从 DEBUG 复制到 RELEASE,例如外部 C++ 库或外部依赖项。

我终于找到了原因。在项目的属性页对话框 -> 链接器文件夹 -> 输入属性页 -> 附加依赖项中,应将其中一个外部库替换为发布版本,即有不同的名字,在我的例子中,QGLViewerd2.libQGLViewer2.lib

【讨论】:

以上是关于必须在传递给 C 运行时函数的 QWidget 和无效参数之前构造一个 QApplication的主要内容,如果未能解决你的问题,请参考以下文章

accept()函数用来告诉Qt,事件处理函数“接收”了这个事件,不要再传递;ignore()函数则告诉Qt,事件处理函数“忽略”了这个事件,需要继续传递(看一下QWidget::mousePress

指针数组内容在传递给 C 中的函数时被擦除

您是不是必须释放传递给 Emscripten 中导出的 C 函数的字符串?

在C语言中,函数实参与形参之间的数据传递方式是( )传递方式。

为啥在使用单指针传递给函数时必须对二维数组进行类型转换?

call()和apply()方法