【问题标题】:Qt ActiveX data typesQt ActiveX 数据类型
【发布时间】:2013-05-21 08:42:42
【问题描述】:

我正在开发一个与 ActiveX 服务器通信的 C++/Qt 应用程序。 我尝试使用一个函数,该函数返回对浮点数组的引用作为参数。函数原型为:

Frequencies([in, out] SAFEARRAY(float)*)

我的代码是:

QList<QVariant> variantList;
object->dynamicCall("Frequencies(QList<QVariant>&)", variantList);

但不幸的是我有以下错误:Type Mismatch in Parameter. Pass an array of type string or real.

阅读this document后,我也尝试了QList&lt;QString&gt;&amp;QList&lt;float&gt;&amp;,但没有成功。

ActiveX 服务器的文档说:Use a safearray of strings (VT_BSTR) or reals (VT_R8 for double or VT_R4 for float).

有什么想法吗?

谢谢!

【问题讨论】:

    标签: c++ qt activex pass-by-reference qaxobject


    【解决方案1】:

    http://qt-project.org/doc/qt-4.8/activeqt.html

    ActiveQt 模块是 Qt 商业版和 Qt 开源版本的一部分。

    http://qt-project.org/doc/qt-4.8/qaxobject.html#details

    http://qt-project.org/doc/qt-4.8/qaxbase.html#details

    这是来自QAXBase 文档的引用:

    调用下面IDL描述的COM接口的方法

    dispinterface IControl
    {
    properties:
        [id(1)] BSTR text;
        [id(2)] IFontDisp *font;
    
    methods:
        [id(6)] void showColumn([in] int i);
        [id(3)] bool addColumn([in] BSTR t);
        [id(4)] int fillList([in, out] SAFEARRAY(VARIANT) *list);
        [id(5)] IDispatch *item([in] int i);
    };
    

    像这样使用QAxBase API:

    QAxObject object("<CLSID>");
    
    QString text = object.property("text").toString();
    object.setProperty("font", QFont("Times New Roman", 12));
    
    connect(this, SIGNAL(clicked(int)), &object, SLOT(showColumn(int)));
    bool ok = object.dynamicCall("addColumn(const QString&)", "Column 1").toBool();
    
    QList<QVariant> varlist;
    QList<QVariant> parameters;
    parameters << QVariant(varlist);
    int n = object.dynamicCall("fillList(QList<QVariant>&)", parameters).toInt();
    
    QAxObject *item = object.querySubItem("item(int)", 5);
    

    请注意,对象应填充的QList 必须作为QVariants 的参数列表中的元素提供。

    所以基本上你需要确保你嵌套了一个 QList,以使你的 SAFEARRAY 工作。

    希望对您有所帮助。

    【讨论】:

    • 不...仍然有相同的错误消息。我尝试使用 QStringList:QStringList list; object-&gt;dynamicCall("Frequencies(QStringList&amp;)", list);。像这样我有一个错误,告诉我数组没有合适的大小。所以我在其中添加了元素:for(int i=0; i&lt;goodSize; i++) list &lt;&lt; "0.0";。然后没有错误消息但是列表的元素没有更新...
    • 所以要嵌套它,你需要有:QStringList stringlist; QList &lt;QVariant&gt; variantList; variantList &lt;&lt; QVariant(stringlist); 看起来如果你不嵌套它就行不通。然后你打电话给object.dynamicCall("Frequencies(QList&lt;QVariant&gt;&amp;)", variantList); 或者object.dynamicCall("Frequencies(QList&lt;QString&gt;&amp;)", variantList);
    • 我不明白为什么要嵌套它。有两个dynamicCall() 函数。第一个:QVariant QAxBase::dynamicCall ( const char * function, const QVariant &amp; var1 = QVariant()...) 只需要一个可能不是列表的参数。第二个:QVariant QAxBase::dynamicCall ( const char * function, QList&lt;QVariant&gt; &amp; vars ) 确实需要一个列表。为什么我不能使用第一个传递 QStringList 的?
    • 因为文档中的注释。 Note that the QList the object should fill has to be provided as an element in the parameter list of QVariants. 这个结构是文档显示它被传递的方式。
    • 所以你的建议是写:QStringList list; for(int i=0; i&lt;goodSize; i++) list &lt;&lt; "0.0"; QList&lt;QVariant&gt; parameters; parameters &lt;&lt; QVariant(list); object-&gt;dynamicCall("Frequencies(QList&lt;QVariant&gt;&amp;)", parameters); for(int i=0; i&lt;list.size(); i++) qDebug() &lt;&lt; list.at(i);。我对吗?我应该写object-&gt;dynamicCall("Frequencies(QList&lt;QVariant&gt;&amp;)", parameters); 还是object-&gt;dynamicCall("Frequencies(QStringList&amp;)", parameters);
    【解决方案2】:

    Qt example 没有显示如何读取结果。这是我的问题...

    QList<QString> values;
    for(int i=0; i<nbFrequencies; i++) {
        values << "0.0";
    }
    QList<QVariant> variantList;
    parameters << QVariant(values);
    object->dynamicCall("Frequencies(QList<QString>&)", variantList);
    
    values = variantList.first().toStringList();
    
    for(int j=0; j<values.size(); j++) {
        qDebug() << values.at(j);
    }
    

    需要读取variantList 的第一个元素并将其转换为QStringList。很简单……

    【讨论】:

      【解决方案3】:

      avtivex 上的 QT 效果不太好。它只是使用 IDispatch 接口来调用方法或属性。 使用activex控件,可以导入MFC库,然后使用COleDispatchDriver的InvokeHelper成员调用方法。就像这样:

      IDispatch* map_itf = NULL;
      map_ctrl_->queryInterface(IID_IDispatch,(void**)&map_itf);
      
      if(map_itf)
      {
          COleDispatchDriver driver(map_itf,FALSE);
      
          static BYTE parms[] =
              VTS_PR4 VTS_PR4 VTS_PR8 VTS_PR8 VTS_I2;
      
          driver.InvokeHelper(0x22, DISPATCH_METHOD, VT_EMPTY, NULL, parms,
              &screen_x, &screen_y, &map_x, &map_y, miScreenToMap);
      }
      

      享受QT,这是一个很棒的项目

      【讨论】:

        猜你喜欢
        • 2011-10-30
        • 1970-01-01
        • 2014-04-09
        • 1970-01-01
        • 1970-01-01
        • 2017-03-23
        • 2021-06-14
        • 1970-01-01
        • 2014-04-01
        相关资源
        最近更新 更多