必须在传递给 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.lib
到 QGLViewer2.lib
。
【讨论】:
以上是关于必须在传递给 C 运行时函数的 QWidget 和无效参数之前构造一个 QApplication的主要内容,如果未能解决你的问题,请参考以下文章
accept()函数用来告诉Qt,事件处理函数“接收”了这个事件,不要再传递;ignore()函数则告诉Qt,事件处理函数“忽略”了这个事件,需要继续传递(看一下QWidget::mousePress
您是不是必须释放传递给 Emscripten 中导出的 C 函数的字符串?