[edit] ActiveQt dynamicCall error: bad parameter count despite the right number



  • Hi guys,
    As you can see, I'm new here, and also quite new to Qt. I'm using it for my BSc thesis since one month.

    To my problem:
    I'm working with sensors, I got a dll for, built with VC++, which provides COM-objects. There's also an IDL file, but no headers. The dumpcpp-approach did not work, as one method returned a null-pointer, so I'm now just using the QAxObjects and dynamicCalls.

    Queries with one parameter like:
    @int setup = dm->dynamicCall("Setup(const int&)",0).toInt();@
    worked fine.

    No I want to call a method with several parameters, defined in the IDL like this:
    @[id(9), helpstring("method GetQuants")] HRESULT GetQuants(LONG SrcIndex, LONG Count, VARIANT* Buffer, LONG DstIndex);@
    The VC++ example provided with the dll, does it like this:
    @component->GetQuants(0, count, &buffer, 0);@

    When I use:
    @QList<QVariant> parameters;
    parameters << 0 << count << analog_buffer << 0;
    ai->dynamicCall("GetQuants(QList<QVariant>&)",parameters);@

    I get:
    "QAxBase: Error calling IDispatch member GetQuants: Type mismatch in parameter 0".

    To make sure I have the right types, I tried something like this:

    @ai->dynamicCall("GetQuants(const int&, const int&, const QVariant&, const int&)",0,count,analog_buffer,0);@

    Here I get the error:
    "Error calling IDispatch member GetQuants: Bad parameter count."
    Although I'm very sure to have the right number of parameters.

    Trying this:
    @ai->dynamicCall("GetQuants(0,96,QVariant(buffer),0");@
    I get "QAxBase: Error calling IDispatch member GetQuants: Type mismatch in parameter 3", so the first three look like being accepted.

    I have been using mingw until recently, which was probably a bad idea with the VC compiled dlls , but I just tried the VC compiler instead and got the same errors.
    I'm not sure if this is an issue with using several parameters, or a problem with the dll not accessed right by Qt. I hope there is a solution for that. Thanks in advance!

    gablbart


    My System:
    Windows XP SP3
    QtCreator 2.0.1
    Qt 4.7.2 VS2008



  • Hi,

    I never tried what you are doing, but I have a guess what is wrong:

    @
    ai->dynamicCall("GetQuants(const int&, const int&, const QVariant&, const int&)",0,count,analog_buffer,0);
    @

    and this

    @
    [id(9), helpstring("method GetQuants")] HRESULT GetQuants(LONG SrcIndex, LONG Count, VARIANT* Buffer, LONG DstIndex);
    @

    does not match. const int& != LONG and VARIANT*!=const QVariant&+

    I would try the following:

    @
    ai->dynamicCall("GetQuants(int, int, const QVariant&, int)",0,count,analog_buffer,0);
    // or
    ai->dynamicCall("GetQuants(int, int, QVariant&, int)",0,count,analog_buffer,0);
    // or
    ai->dynamicCall("GetQuants(int, int, QVariant*, int)",0,count,&analog_buffer,0);
    @

    Do you know, why the VARIANT is a pointer? is it an out parameter?



  • Hi Gerolf,
    thank you for your hints!

    If I do it like you suggested, I get:

    "QAxBase: Error calling IDispatch member GetQuants: Bad parameter count"

    The last example gives me:

    " 'QVariant::QVariant': cannot access private member declared in class 'QVariant' "

    I'm not sure, why the VARIANT is a pointer. The VARIANT buffer is filled with a SAFEARRAY by
    @[id(10), helpstring("method CreateCompatibleBuffer")] HRESULT CreateCompatibleBuffer(VARIANT* buffer);@
    ,as the documentation states, before I fill it with GetQuants().



  • Hi, I Got the exactly the same problem, how do you solve it?



  • Hi SpaceCowboy,
    the solution was to switch to the MSVC compiler. You get a free version with Visual Studio Express, but I'm not sure wether it has support for ActiveX/COM stuff. So maybe you need the full version. Good luck!

    gablbart



  • Hi,
    I solved the issue too, in a simpler way (11 parameters):

    @QList<QVariant> varList;

    varList << x << y << HFont << NameEl << 0 << 0 << 0 << 0 << 0 << 0 << "Text" << 0 << 0;

    Layout->querySubObject("DrawingObjects()")->dynamicCall("AddText(double x, double y, double Height, QString Text, double RotationAngle = 0, bool Flipped = 0, QString FontName = 0, bool Bold = 0, bool Italic = 0, bool DrawAsPolygons = 0, QString LayerName = 0, bool UseProcessLayers = 0, QString LayerMapping = 0)",varList);@

    Qt documentation of ->dynamicCall() should be reworded in a clearer way...
    Regards



  • [quote author="SpaceCowboy2" date="1341218265"]Qt documentation of ->dynamicCall() should be reworded in a clearer way...[/quote]
    That is a good idea, but do you have a concrete suggestion for that?



  • I think it's sufficient to add the bold text and the example code to the current QAxBase::dynamicCall documentation as below:

    QVariant QAxBase::dynamicCall ( const char * function, QList<QVariant> & vars )
    This is an overloaded function.
    Calls the COM object's method function, passing the parameters in vars, and returns the value returned by the method. Parameters data types must be specified like this:

    @QList<QVariant> varlist;
    varlist << true << 123 << 1.2345;
    int n = object.dynamicCall("methodToCall(bool,int,double)", varlist).toInt();@

    If the method does not return a value or when the function call failed this function returns an invalid QVariant object.
    The QVariant objects in vars are updated when the method has out-parameters.



  • Sounds like a good suggestion. You might:

    create a bugreport with your suggestion

    Better yet, a patch

    for now, create a doc note on this.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.