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. Task-number: QTBUG-119952 Change-Id: Ic4437116eed5e15226449bdabe48ab657cb14dc3 Reviewed-by: Marc Mutz <marc.mutz@qt.io> (cherry picked from commit 101ab278913e3bacc7c0596ae0a5bf3c0fa2f922) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
0604ce57ea
commit
7f9e5ccd55
@ -69,7 +69,7 @@ private:
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
class QJniArrayBase : public QJniObject
|
class QJniArrayBase
|
||||||
{
|
{
|
||||||
// for SFINAE'ing out the fromContainer named constructor
|
// for SFINAE'ing out the fromContainer named constructor
|
||||||
template <typename Container, typename = void> struct CanConvertHelper : std::false_type {};
|
template <typename Container, typename = void> struct CanConvertHelper : std::false_type {};
|
||||||
@ -83,9 +83,15 @@ public:
|
|||||||
using size_type = jsize;
|
using size_type = jsize;
|
||||||
using difference_type = size_type;
|
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
|
size_type size() const
|
||||||
{
|
{
|
||||||
if (jarray array = object<jarray>())
|
if (jarray array = m_object.object<jarray>())
|
||||||
return jniEnv()->GetArrayLength(array);
|
return jniEnv()->GetArrayLength(array);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -141,22 +147,25 @@ protected:
|
|||||||
~QJniArrayBase() = default;
|
~QJniArrayBase() = default;
|
||||||
|
|
||||||
explicit QJniArrayBase(jarray array)
|
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)
|
explicit QJniArrayBase(const QJniObject &object)
|
||||||
: QJniObject(object)
|
: m_object(object)
|
||||||
{}
|
{}
|
||||||
explicit QJniArrayBase(QJniObject &&object) noexcept
|
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>
|
template <typename ElementType, typename List, typename NewFn, typename SetFn>
|
||||||
static auto makeArray(List &&list, NewFn &&newArray, SetFn &&setRegion);
|
static auto makeArray(List &&list, NewFn &&newArray, SetFn &&setRegion);
|
||||||
template <typename List>
|
template <typename List>
|
||||||
static auto makeObjectArray(List &&list);
|
static auto makeObjectArray(List &&list);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QJniObject m_object;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -102,7 +102,7 @@ static QString fetchFont(const QString &query)
|
|||||||
HashSet innerSet;
|
HashSet innerSet;
|
||||||
Q_ASSERT(outerList.isValid() && innerSet.isValid());
|
Q_ASSERT(outerList.isValid() && innerSet.isValid());
|
||||||
|
|
||||||
for (QJniObject signature : signatures) {
|
for (const auto &signature : signatures) {
|
||||||
const QJniArray<jbyte> byteArray = signature.callMethod<jbyte[]>("toByteArray");
|
const QJniArray<jbyte> byteArray = signature.callMethod<jbyte[]>("toByteArray");
|
||||||
|
|
||||||
// add takes an Object, not an Array
|
// add takes an Object, not an Array
|
||||||
|
Loading…
x
Reference in New Issue
Block a user