summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2023-03-18 10:34:01 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-03-22 16:51:34 +0000
commit41c9f8eb94a789cedace5ab4da66e37cc3639b01 (patch)
tree3874063a9df20a70ca9cfaed4a828539c02408e7
parent97aa42ab8bacab05717a4d951e457defcd84f7aa (diff)
downloadqtactiveqt-41c9f8eb94a789cedace5ab4da66e37cc3639b01.tar.gz
Fix handling of out-parameters that are of VARIANT-type
Qt knows about QVariant as a built-in meta type, QMetaType::QVariant. It is no longer mapped to user type. COM objects expect that untyped out- parameters, which are mapped to QVariant& by ActiveQt, are passed in as VT_VARIANT|VT_BYREF. Update our variant-conversion logic accordingly. If the typeName, which comes from the generated function signature, is "QVariant", then QMetaType::fromName(typeName) will always be QMetaType::QVariant, and had to be passed as VT_VARIANT. Fix the logic for deciding whether we have to write back the out- parameters so that it works when QAxScript::call is used. We need to write back no matter whether it's a property or a getter, so check whether any bit is set, not if both are set. Add some test for this. Not cherry-picking this further back, the auto-test coverage of ActiveQt is not good enough to make sure that we don't break any subtle usecases in e.g. QAxServer, and the usage of QAxScript does not seem to be very wide. Fixes: QTBUG-111718 Change-Id: I239f71c3637ea9f32dff5123a8ada96e0a894371 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> (cherry picked from commit e640503b65c4d786edc9f005a1c3f6f66e87793d) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/activeqt/container/qaxbase.cpp2
-rw-r--r--src/activeqt/shared/qaxtypes.cpp2
-rw-r--r--tests/auto/qaxscript/tst_qaxscript.cpp36
3 files changed, 38 insertions, 2 deletions
diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp
index c3b9b0a..973347b 100644
--- a/src/activeqt/container/qaxbase.cpp
+++ b/src/activeqt/container/qaxbase.cpp
@@ -3771,7 +3771,7 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> &
hres = Invoke(disp, dispid, IID_NULL, LOCALE_USER_DEFAULT, disptype, &params, nullptr, &excepinfo, &argerr);
}
- if (disptype == (DISPATCH_METHOD|DISPATCH_PROPERTYGET) && hres == S_OK && varc) {
+ if ((disptype & (DISPATCH_METHOD|DISPATCH_PROPERTYGET)) && hres == S_OK && varc) {
for (qsizetype i = 0; i < varc; ++i)
if ((arg[varc-i-1].vt & VT_BYREF) || outArgs[i]) // update out-parameters
vars[i] = VARIANTToQVariant(arg[varc-i-1], vars.at(i).typeName());
diff --git a/src/activeqt/shared/qaxtypes.cpp b/src/activeqt/shared/qaxtypes.cpp
index ecf6acd..f4f367a 100644
--- a/src/activeqt/shared/qaxtypes.cpp
+++ b/src/activeqt/shared/qaxtypes.cpp
@@ -238,7 +238,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
return QVariantToVARIANT(var, *arg.pvarVal, typeName, false);
}
- if (out && proptype == QMetaType::User && typeName == "QVariant") {
+ if (out && proptype == QMetaType::QVariant) {
VARIANT *pVariant = new VARIANT;
QVariantToVARIANT(var, *pVariant, QByteArray(), false);
arg.vt = VT_VARIANT|VT_BYREF;
diff --git a/tests/auto/qaxscript/tst_qaxscript.cpp b/tests/auto/qaxscript/tst_qaxscript.cpp
index 227e853..454b347 100644
--- a/tests/auto/qaxscript/tst_qaxscript.cpp
+++ b/tests/auto/qaxscript/tst_qaxscript.cpp
@@ -14,6 +14,7 @@ class tst_QAxScript : public QObject
private slots:
void scriptReturnValue();
+ void scriptOutParameters();
};
void tst_QAxScript::scriptReturnValue()
@@ -30,5 +31,40 @@ void tst_QAxScript::scriptReturnValue()
QCOMPARE(result, QVariant(u"test"_s));
}
+void tst_QAxScript::scriptOutParameters()
+{
+ QAxScriptManager scriptManager;
+ const auto scriptCode = uR"VB(
+ Function GetProductName(ByRef manufacturer, ByRef name, ByRef version)
+ manufacturer = "The Qt Company"
+ name = "ActiveQt"
+ version = 650
+ On Error Resume Next
+ GetProductName = 42
+ End Function
+ )VB"_s;
+
+ QAxScript *script = scriptManager.load(scriptCode, u"Test"_s, u"VBScript"_s);
+ QVERIFY2(script, "Unable to load script (CoInitializeEx() called?)");
+
+ QVariant returnValue;
+ QList<QVariant> results = {{}, {}, {}};
+
+ returnValue = script->scriptEngine()->dynamicCall("GetProductName(QVariant&,QVariant&,QVariant&)", results);
+ QCOMPARE(returnValue, 42);
+ QCOMPARE(results.size(), 3);
+ QCOMPARE(results.at(0), "The Qt Company");
+ QCOMPARE(results.at(1), "ActiveQt");
+ QCOMPARE(results.at(2), 650);
+
+ results = {{}, {}, {}};
+ returnValue = script->call("GetProductName(QVariant&,QVariant&,QVariant&)", results);
+ QCOMPARE(returnValue, 42);
+ QCOMPARE(results.size(), 3);
+ QCOMPARE(results.at(0), "The Qt Company");
+ QCOMPARE(results.at(1), "ActiveQt");
+ QCOMPARE(results.at(2), 650);
+}
+
QTEST_MAIN(tst_QAxScript)
#include "tst_qaxscript.moc"