Вопрос

I am developing a C++/Qt application that communicates with an ActiveX server. I try to use a function that returns a reference to an array of floats as a parameter. The function prototype is:

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

My code is:

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

But unfortunately I have the following error: Type Mismatch in Parameter. Pass an array of type string or real.

After reading this document I also tried QList<QString>& and QList<float>& with no success.

The documentation of the ActiveX server says: Use a safearray of strings (VT_BSTR) or reals (VT_R8 for double or VT_R4 for float).

Any idea?

Thanks!

Это было полезно?

Решение 2

The Qt example doesn't show how to read the results. It was my problem...

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);
}

It is necessary to read the first element of variantList and to convert it to a QStringList. Very simply...

Другие советы

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

The ActiveQt modules are part of the Qt Commercial Edition and the Open Source Versions of Qt.

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

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

Here is a quote from the documentation for QAXBase:

To call the methods of a COM interface described by the following IDL

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);
};

use the QAxBase API like this:

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);

Note that the QList the object should fill has to be provided as an element in the parameter list of QVariants.

So basically you need to make sure that you are nesting a QList, in order to make your SAFEARRAY work.

Hope that helps.

QT on avtivex works not so good.It just use IDispatch interface to invoke the method or property. With an activex control,you can import MFC library then use COleDispatchDriver's InvokeHelper member to invoke the method.just like this:

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);
}

Enjoy QT,it's a great project

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top