我们正在构建一个包含一些QObject和QWidgets的库。我们的想法是使用ActiveX(QAxContainer)提供COM对象,以便它们可以嵌入并与其他语言结合使用(在本例中为托管C#)。
我们正在使用的一些对象将与Qt Quick集成,为此我们使用的是QQuickWidget。在QQuickWidget构造期间,它将调用QCoreApplication :: arguments(),这会导致访问冲突读取:
Exception thrown at 0x00007ffc43f12fc0 (ucrtbased.dll) in WinClient.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff
将以下类导出到ActiveX小部件将导致崩溃:
#include <QWidget>
#include <ActiveQt/QAxBindable>
class TestAxWidget: public QWidget, public QAxBindable
{
Q_OBJECT
Q_CLASSINFO("ClassID", "{377794ac-85f2-4e2c-be17-f2852d85fa61}")
Q_CLASSINFO("InterfaceID", "{8b3a6ef3-9d17-47f7-99a8-cd96d0d922dd}")
Q_CLASSINFO("EventsID", "{12e9000e-017e-454e-a641-73c9p8349d77}")
Q_CLASSINFO("CoClassAlias", "TestAxWidget")
Q_CLASSINFO("RegisterObject", "yes")
public:
explicit TestAxWidget(QWidget * parent = Q_NULLPTR)
: QWidget(parent)
{
QCoreApplication::arguments();
}
Q_DISABLE_COPY(TestAxWidget)
};
堆栈跟踪:
ucrtbased.dll!strlen() + 0x10 bytes
Qt5Cored.dll!QString::fromLocal8Bit(const char * str, int size) Line 539 + 0x19 bytes C++
Qt5Cored.dll!QCoreApplication::arguments() Line 2313 + 0x1e bytes C++
有关如何解决此问题的任何建议?
更新
在使用Qt源进行一些进一步调试之后,我发现给予QCoreApplication()的argc
被初始化为0(零)。
当调用QCoreApplication :: arguments()时,argc的值已经变为某个随机高值!= 0,这显然会导致异常。
我在VS2015中使用了Data Breakpoint
来确定argc的值何时发生变化,并且似乎会被clr.dll
定期更改。我怎么能阻止这个?我做了一些根本错误的事情吗?
目前在Windows 10 x64 VS2015上使用Qt 5.6.2
答案 0 :(得分:0)
我认为解决这个问题的唯一方法是在不更改主应用程序(我认为是C#)的情况下,在库中创建QApplication实例,并运行QApplication :: exec以从/向QWidgets实例发送GUI消息。
答案 1 :(得分:0)
显然,当QAxServerBase.cpp中的QApplication由函数CreateInstanceHelper:
...
if (!qApp) {
qax_ownQApp = true;
int argc = 0;
new QApplication(argc, 0);
}
...
应用程序崩溃,因为传递的参数argc
是在堆栈上创建的,并且不会超过QApplication实例。
版本5.9.0中有一个错误修复: https://bugreports.qt.io/browse/QTBUG-59047