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
|
||||
template <typename Container, typename = void> struct CanConvertHelper : std::false_type {};
|
||||
@ -83,9 +83,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;
|
||||
}
|
||||
@ -141,22 +147,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>
|
||||
|
@ -102,7 +102,7 @@ static QString fetchFont(const QString &query)
|
||||
HashSet innerSet;
|
||||
Q_ASSERT(outerList.isValid() && innerSet.isValid());
|
||||
|
||||
for (QJniObject signature : signatures) {
|
||||
for (const auto &signature : signatures) {
|
||||
const QJniArray<jbyte> byteArray = signature.callMethod<jbyte[]>("toByteArray");
|
||||
|
||||
// add takes an Object, not an Array
|
||||
|
Loading…
x
Reference in New Issue
Block a user