qt call ocx
-
1、environment:windows10 64bit; qt 5.15.2 ; msvc2019 64bit;qt creator 5.0.3
2、QAxObject::generateDocumentation() ,The api exported by the method is as follows:
slot: int GetStagePosition(QVariant& x, QVariant& y, QVariant& z, QVariant& t, QVariant& r, QVariant& m);
The documentation gives examples of calls:
int GetStagePosition (QVariant& x, QVariant& y, QVariant& z, QVariant& t, QVariant& r, QVariant& m) [slot] Connect a signal to this slot: QObject::connect(sender, SIGNAL(someSignal(QVariant&, QVariant&, QVariant&, QVariant&, QVariant&, QVariant&)), object, SLOT(GetStagePosition(QVariant&, QVariant&, QVariant&, QVariant&, QVariant&, QVariant&))); Or call the function directly: QVariantList params = ... int result = object->dynamicCall("GetStagePosition(QVariant&, QVariant&, QVariant&, QVariant&, QVariant&, QVariant&)", params).toInt();
3、First attempt:
QObject::connect(this, SIGNAL( sig_GetStagePosition(QVariant&,QVariant&,QVariant&,QVariant&,QVariant&,QVariant&) ), m_axObject, SLOT( GetStagePosition(QVariant&,QVariant&,QVariant&,QVariant&,QVariant&,QVariant&) ));
sig_GetStagePosition:This is my custom signal.
m_axObject:This is the QAxObject object.I trigger the signal inside the button,
QVariant varX, varY, varZ, varT, varR, varM; emit sig_GetStagePosition(varX, varY, varZ, varT, varR, varM);
The console outputs an error when I click the button to trigger the signal:
QAxBase: Error calling IDispatch member GetStagePosition: Type mismatch in parameter 0
4、When I tried the second method:
QVariant qvarX, qvarY, qvarZ, qvarT, qvarR, qvarM; QVariantList args; args << qvarX << qvarY << qvarZ << qvarT << qvarR << qvarM; m_axObject->dynamicCall("GetStagePosition(QVariant&, QVariant&, QVariant&, QVariant&, QVariant&, QVariant&)", args);
When I click the button to run it, it still reports the same error:
QAxBase: Error calling IDispatch member GetStagePosition: Type mismatch in parameter 0
I don't know what the problem is, thank you very much for answering my question
-
1、environment:windows10 64bit; qt 5.15.2 ; msvc2019 64bit;qt creator 5.0.3
2、QAxObject::generateDocumentation() ,The api exported by the method is as follows:
slot: int GetStagePosition(QVariant& x, QVariant& y, QVariant& z, QVariant& t, QVariant& r, QVariant& m);
The documentation gives examples of calls:
int GetStagePosition (QVariant& x, QVariant& y, QVariant& z, QVariant& t, QVariant& r, QVariant& m) [slot] Connect a signal to this slot: QObject::connect(sender, SIGNAL(someSignal(QVariant&, QVariant&, QVariant&, QVariant&, QVariant&, QVariant&)), object, SLOT(GetStagePosition(QVariant&, QVariant&, QVariant&, QVariant&, QVariant&, QVariant&))); Or call the function directly: QVariantList params = ... int result = object->dynamicCall("GetStagePosition(QVariant&, QVariant&, QVariant&, QVariant&, QVariant&, QVariant&)", params).toInt();
3、First attempt:
QObject::connect(this, SIGNAL( sig_GetStagePosition(QVariant&,QVariant&,QVariant&,QVariant&,QVariant&,QVariant&) ), m_axObject, SLOT( GetStagePosition(QVariant&,QVariant&,QVariant&,QVariant&,QVariant&,QVariant&) ));
sig_GetStagePosition:This is my custom signal.
m_axObject:This is the QAxObject object.I trigger the signal inside the button,
QVariant varX, varY, varZ, varT, varR, varM; emit sig_GetStagePosition(varX, varY, varZ, varT, varR, varM);
The console outputs an error when I click the button to trigger the signal:
QAxBase: Error calling IDispatch member GetStagePosition: Type mismatch in parameter 0
4、When I tried the second method:
QVariant qvarX, qvarY, qvarZ, qvarT, qvarR, qvarM; QVariantList args; args << qvarX << qvarY << qvarZ << qvarT << qvarR << qvarM; m_axObject->dynamicCall("GetStagePosition(QVariant&, QVariant&, QVariant&, QVariant&, QVariant&, QVariant&)", args);
When I click the button to run it, it still reports the same error:
QAxBase: Error calling IDispatch member GetStagePosition: Type mismatch in parameter 0
I don't know what the problem is, thank you very much for answering my question
@xiaolin
I think the following is an outline of the answer.Your method requires
QVariant &
parameters, i.e. non-const
references toQVariant
s, because these are not "in" parameters, they are "out" parameters whichGetStagePosition
is going to fill. Right?But QVariant QAxBase::dynamicCall(...) accepts only
const QVariant &
parameters, i.e. "in"-only parameters. And it saysAll parameters are passed as strings; it depends on the control whether they are interpreted correctly, and is slower than using the prototype with correctly typed parameters
Hence the "type mismatch" error, and this is never going to work.
I think that
QAxBase::dynamicCall()
can only be called with in-string parameters. To do what you want --- pass in "out"-QVariant &
parameters --- I guess you have to usequeryInterface()
and call the function directly with the desired parameters, as shown in the last example at that link.Having said that, I see there is a different overload: QVariant QAxBase::dynamicCall(const char *function, QList<QVariant> &vars), and that says:
The QVariant objects in vars are updated when the method has out-parameters.
So that ought work. For that I suspect/wonder whether your call should not specify the parameters? So maybe:
m_axObject->dynamicCall("GetStagePosition", args); // or m_axObject->dynamicCall("GetStagePosition()", args); // or m_axObject->dynamicCall("GetStagePosition(QList<QVariant> &)", args);
? I am unable to find any example on the web which uses this overload, so you may have to play!
You might want to also read https://www.codeproject.com/Tips/751240/Using-COM-Binary-Interface-with-Cplusplus and and/or https://www.qtcentre.org/threads/49796-dynamicCall-with-in-out-SAFEARRAY(VARIANT_BOOL)*-parameter
-
@xiaolin
I think the following is an outline of the answer.Your method requires
QVariant &
parameters, i.e. non-const
references toQVariant
s, because these are not "in" parameters, they are "out" parameters whichGetStagePosition
is going to fill. Right?But QVariant QAxBase::dynamicCall(...) accepts only
const QVariant &
parameters, i.e. "in"-only parameters. And it saysAll parameters are passed as strings; it depends on the control whether they are interpreted correctly, and is slower than using the prototype with correctly typed parameters
Hence the "type mismatch" error, and this is never going to work.
I think that
QAxBase::dynamicCall()
can only be called with in-string parameters. To do what you want --- pass in "out"-QVariant &
parameters --- I guess you have to usequeryInterface()
and call the function directly with the desired parameters, as shown in the last example at that link.Having said that, I see there is a different overload: QVariant QAxBase::dynamicCall(const char *function, QList<QVariant> &vars), and that says:
The QVariant objects in vars are updated when the method has out-parameters.
So that ought work. For that I suspect/wonder whether your call should not specify the parameters? So maybe:
m_axObject->dynamicCall("GetStagePosition", args); // or m_axObject->dynamicCall("GetStagePosition()", args); // or m_axObject->dynamicCall("GetStagePosition(QList<QVariant> &)", args);
? I am unable to find any example on the web which uses this overload, so you may have to play!
You might want to also read https://www.codeproject.com/Tips/751240/Using-COM-Binary-Interface-with-Cplusplus and and/or https://www.qtcentre.org/threads/49796-dynamicCall-with-in-out-SAFEARRAY(VARIANT_BOOL)*-parameter
@JonB Thank you very much for your patient answer,Thanks.
I understand that adding a const argument cannot be used as an out parameters,So I also tried dynamicCall() second overload.Based on the attempt you gave me, I also ran the test again.
First:
QVariant qvarX, qvarY, qvarZ, qvarT, qvarR, qvarM; QList<QVariant> args; args << qvarX << qvarY << qvarZ << qvarT << qvarR << qvarM; m_axObject->dynamicCall("GetStagePosition", args);
the same error:
QAxBase: Error calling IDispatch member GetStagePosition: Type mismatch in parameter 0
Second:
QVariant qvarX, qvarY, qvarZ, qvarT, qvarR, qvarM; QList<QVariant> args; args << qvarX << qvarY << qvarZ << qvarT << qvarR << qvarM; m_axObject->dynamicCall("GetStagePosition()", args);
Error occurs change:
QAxBase: Error calling IDispatch member GetStagePosition: Non-optional parameter missing
Third:
QVariant qvarX, qvarY, qvarZ, qvarT, qvarR, qvarM; QList<QVariant> args; args << qvarX << qvarY << qvarZ << qvarT << qvarR << qvarM; m_axObject->dynamicCall("GetStagePosition(QList<QVariant> &)", args);
It's the same mistake:
QAxBase: Error calling IDispatch member GetStagePosition: Type mismatch in parameter 0
I read the link you gave at the end,I didn't understand a few parts of the article.
inline int GetSignalIds(QVariant& ids);
GetSignalIds,The parameter type for this function is the same as mine.
number = Job.GetSignalIds(*SignalIds);
Why is the pointer type passed in the last call.And how is this variable SignalIds defined, the article does not give, a little confusing.
-
@JonB Thank you very much for your patient answer,Thanks.
I understand that adding a const argument cannot be used as an out parameters,So I also tried dynamicCall() second overload.Based on the attempt you gave me, I also ran the test again.
First:
QVariant qvarX, qvarY, qvarZ, qvarT, qvarR, qvarM; QList<QVariant> args; args << qvarX << qvarY << qvarZ << qvarT << qvarR << qvarM; m_axObject->dynamicCall("GetStagePosition", args);
the same error:
QAxBase: Error calling IDispatch member GetStagePosition: Type mismatch in parameter 0
Second:
QVariant qvarX, qvarY, qvarZ, qvarT, qvarR, qvarM; QList<QVariant> args; args << qvarX << qvarY << qvarZ << qvarT << qvarR << qvarM; m_axObject->dynamicCall("GetStagePosition()", args);
Error occurs change:
QAxBase: Error calling IDispatch member GetStagePosition: Non-optional parameter missing
Third:
QVariant qvarX, qvarY, qvarZ, qvarT, qvarR, qvarM; QList<QVariant> args; args << qvarX << qvarY << qvarZ << qvarT << qvarR << qvarM; m_axObject->dynamicCall("GetStagePosition(QList<QVariant> &)", args);
It's the same mistake:
QAxBase: Error calling IDispatch member GetStagePosition: Type mismatch in parameter 0
I read the link you gave at the end,I didn't understand a few parts of the article.
inline int GetSignalIds(QVariant& ids);
GetSignalIds,The parameter type for this function is the same as mine.
number = Job.GetSignalIds(*SignalIds);
Why is the pointer type passed in the last call.And how is this variable SignalIds defined, the article does not give, a little confusing.
@xiaolin
I know no more than I have written. If you cannot getdynamicCall()
to work suggest you try to make the call directly via the mechanism illustrated at the end of section https://doc.qt.io/qt-6/qaxbase.html#dynamicCall usingqueryInterface()
. -
Hi, using QVariants for ByRef (out) parameters for calling into OCX dlls are tricky at best (if you google it seems no one has got it to work).
Perhaps you could trick QAxBase by not mentioning QVariants in the call, say like this:QVariantList params = ... int result = object->dynamicCall("GetStagePosition(double&, double&, double&, double&, double&, double&)", params);
-
Hi, using QVariants for ByRef (out) parameters for calling into OCX dlls are tricky at best (if you google it seems no one has got it to work).
Perhaps you could trick QAxBase by not mentioning QVariants in the call, say like this:QVariantList params = ... int result = object->dynamicCall("GetStagePosition(double&, double&, double&, double&, double&, double&)", params);
@hskoglund Thanks.
I tried, but that didn't seem to work either.QVariant varX, varY, varZ, varT, varR, varM; QVariantList args; args << varX << varY << varZ << varT << varR << varM; m_axObject->dynamicCall("GetStagePosition(double&, double&, double&, double&, double&, double&)", args);
The same error is reported
QAxBase: Error calling IDispatch member GetStagePosition: Type mismatch in parameter 0
-
@xiaolin
I know no more than I have written. If you cannot getdynamicCall()
to work suggest you try to make the call directly via the mechanism illustrated at the end of section https://doc.qt.io/qt-6/qaxbase.html#dynamicCall usingqueryInterface()
.