From 101ab278913e3bacc7c0596ae0a5bf3c0fa2f922 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Mon, 22 Jan 2024 16:09:04 +0100 Subject: QJniArray: don't subclass QJniObject QJniObject is not prepared for being subclassed (no virtual destructor), and doing so is formally UB. Instead of making QJniArray(Base) a QJniObject subclass, give it a QJniObject member and make it convertible to/from QJniObject. Existing code still works with this change, even though it removes all the inherited QJniObject APIs for accessing fields and methods. However, as the Java array classes have a very narrow and well-defined API anyway we could, if needed, add those as C++ member functions instead of going through calling-by-string. Found during API review. Pick-to: 6.7 Task-number: QTBUG-119952 Change-Id: Ic4437116eed5e15226449bdabe48ab657cb14dc3 Reviewed-by: Marc Mutz --- src/corelib/kernel/qjniarray.h | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qjniarray.h b/src/corelib/kernel/qjniarray.h index 22c1113f42..5dd3588ac4 100644 --- a/src/corelib/kernel/qjniarray.h +++ b/src/corelib/kernel/qjniarray.h @@ -85,7 +85,7 @@ private: {} }; -class QJniArrayBase : public QJniObject +class QJniArrayBase { // for SFINAE'ing out the fromContainer named constructor template struct CanConvertHelper : std::false_type {}; @@ -99,9 +99,15 @@ public: using size_type = jsize; using difference_type = size_type; + operator QJniObject() const { return m_object; } + + template + T object() const { return m_object.object(); } + bool isValid() const { return m_object.isValid(); } + size_type size() const { - if (jarray array = object()) + if (jarray array = m_object.object()) return jniEnv()->GetArrayLength(array); return 0; } @@ -160,22 +166,25 @@ protected: ~QJniArrayBase() = default; explicit QJniArrayBase(jarray array) - : QJniObject(static_cast(array)) + : m_object(static_cast(array)) { - static_assert(sizeof(QJniArrayBase) == sizeof(QJniObject), - "QJniArrayBase must have the same size as QJniObject!"); } explicit QJniArrayBase(const QJniObject &object) - : QJniObject(object) + : m_object(object) {} explicit QJniArrayBase(QJniObject &&object) noexcept - : QJniObject(std::move(object)) + : m_object(std::move(object)) {} + JNIEnv *jniEnv() const noexcept { return QJniEnvironment::getJniEnv(); } + template static auto makeArray(List &&list, NewFn &&newArray, SetFn &&setRegion); template static auto makeObjectArray(List &&list); + +private: + QJniObject m_object; }; template -- cgit v1.2.3