使用ActiveX服务器

时间:2017-03-14 09:33:14

标签: c++ qt activex

我们正在构建一个包含一些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

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