diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2024-01-22 16:09:04 +0100 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2024-01-29 16:06:47 +0100 |
commit | 101ab278913e3bacc7c0596ae0a5bf3c0fa2f922 (patch) | |
tree | 66837c5ed25734465555ecb4b258a5baaa2e2d0b /src/corelib/kernel | |
parent | 23fb1c50eecaed2f5a3ebfe95e72892c054e4414 (diff) |
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 <marc.mutz@qt.io>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qjniarray.h | 23 |
1 files changed, 16 insertions, 7 deletions
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 <typename Container, typename = void> 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 <typename T = jobject> + T object() const { return m_object.object<T>(); } + bool isValid() const { return m_object.isValid(); } + size_type size() const { - if (jarray array = object<jarray>()) + if (jarray array = m_object.object<jarray>()) return jniEnv()->GetArrayLength(array); return 0; } @@ -160,22 +166,25 @@ protected: ~QJniArrayBase() = default; explicit QJniArrayBase(jarray array) - : QJniObject(static_cast<jobject>(array)) + : m_object(static_cast<jobject>(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 <typename ElementType, typename List, typename NewFn, typename SetFn> static auto makeArray(List &&list, NewFn &&newArray, SetFn &&setRegion); template <typename List> static auto makeObjectArray(List &&list); + +private: + QJniObject m_object; }; template <typename T> |