We are building a library that contains a few QObjects and QWidgets. The idea is to provide COM objects using ActiveX (QAxContainer) so they can be embedded and used in conjunction with other languages (in this case, managed C#).
Some of the objects that we are using will integrate with Qt Quick and to do this we are using QQuickWidget. During the QQuickWidget construction it will invoke QCoreApplication::arguments() which leads to an access violation reading:
Exception thrown at 0x00007ffc43f12fc0 (ucrtbased.dll) in WinClient.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff
Exporting the following class to an ActiveX widget will lead to the crash:
#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)
};
And stack trace:
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++
Any suggestions on how to solve this?
Update
After some further debugging using the Qt sources I've found that the argc
given to the QCoreApplication() is initialized to 0 (zero).
When QCoreApplication::arguments() is invoked the value of argc has changed to some random high value != 0, which will obviously lead to an exception.
I've used a Data Breakpoint
in VS2015 to identify when the value of argc is changed and it seems to periodically be changed by clr.dll
. How can I prevent this? am I doing something fundamentally wrong?
Currently using Qt 5.6.2 on Windows 10 x64 VS2015
Apparently there is a bug when the QApplication is instansiated in QAxServerBase.cpp, by function CreateInstanceHelper:
...
if (!qApp) {
qax_ownQApp = true;
int argc = 0;
new QApplication(argc, 0);
}
...
The application crashes since the passed in argument argc
is created on the stack and doesn't outlive the QApplication-instance.
There is a bug-fix for this in version 5.9.0: https://bugreports.qt.io/browse/QTBUG-59047