summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qjniobject.h
diff options
context:
space:
mode:
authorAssam Boudjelthia <assam.boudjelthia@qt.io>2021-04-15 16:52:44 +0300
committerAssam Boudjelthia <assam.boudjelthia@qt.io>2021-04-23 15:43:28 +0300
commitf4e23bf3deb69131f78eb78a1cb06da0fe72d9d4 (patch)
tree423bb588c65c6db91312f6e0ed9b1895f5daaa3f /src/corelib/kernel/qjniobject.h
parent2666f3e37d6c8f2125f77f8de2cf5582ead7c18e (diff)
Fix QJniObject templates implementations
Define the template calls in the header to allow for better type handling and checking with constexpr and avoid overuse of macros. Depending on the type provided in the QJniObject's call, the signatures and the correct JNI function variant is used. If a type is not supported a static_assert throws a compiler error. Pick-to: 6.1 6.1.0 Change-Id: I8a4d3ce85e1ff76ef385633f2a68511fffd12e55 Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io> Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/corelib/kernel/qjniobject.h')
-rw-r--r--src/corelib/kernel/qjniobject.h672
1 files changed, 606 insertions, 66 deletions
diff --git a/src/corelib/kernel/qjniobject.h b/src/corelib/kernel/qjniobject.h
index 0f88695e73..83d64ad485 100644
--- a/src/corelib/kernel/qjniobject.h
+++ b/src/corelib/kernel/qjniobject.h
@@ -40,14 +40,11 @@
#ifndef QJNIOBJECT_H
#define QJNIOBJECT_H
-#include <QtCore/QSharedPointer>
+#include <QtCore/qsharedpointer.h>
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
#include <jni.h>
-#else
-class jclass;
-class jobject;
-#endif
+#include <QtCore/qjnienvironment.h>
QT_BEGIN_NAMESPACE
@@ -64,85 +61,375 @@ public:
QJniObject(jobject globalRef);
~QJniObject();
- template <typename T>
- T object() const;
jobject object() const;
+ template <typename T> T object() const
+ {
+ assertJniObjectType<T>();
+ return static_cast<T>(javaObject());
+ }
template <typename T>
- T callMethod(const char *methodName, const char *signature, ...) const;
+ T callMethod(const char *methodName, const char *signature, ...) const
+ {
+ assertJniPrimitiveType<T>();
+ QJniEnvironment env;
+ T res{};
+ jmethodID id = getCachedMethodID(env.jniEnv(), methodName, signature);
+ if (id) {
+ va_list args;
+ va_start(args, signature);
+ callMethodForType<T>(env.jniEnv(), res, object(), id, args);
+ va_end(args);
+ if (env.checkAndClearExceptions())
+ res = {};
+ }
+ return res;
+ }
+
+ template <>
+ void callMethod<void>(const char *methodName, const char *signature, ...) const
+ {
+ QJniEnvironment env;
+ jmethodID id = getCachedMethodID(env.jniEnv(), methodName, signature);
+ if (id) {
+ va_list args;
+ va_start(args, signature);
+ callVoidMethodV(env.jniEnv(), id, args);
+ va_end(args);
+ env.checkAndClearExceptions();
+ }
+ }
+
template <typename T>
- T callMethod(const char *methodName) const;
+ T callMethod(const char *methodName) const
+ {
+ assertJniPrimitiveType<T>();
+ constexpr const char *signature = getTypeSignature<T>();
+ return callMethod<T>(methodName, QByteArray(signature).prepend("()").constData());
+ }
+
+ template <>
+ void callMethod<void>(const char *methodName) const
+ {
+ callMethod<void>(methodName, "()V");
+ }
+
template <typename T>
- QJniObject callObjectMethod(const char *methodName) const;
+ QJniObject callObjectMethod(const char *methodName) const
+ {
+ assertJniObjectType<T>();
+ constexpr const char *signature = getTypeSignature<T>();
+ return callObjectMethod(methodName, QByteArray(signature).prepend("()").constData());
+ }
+
QJniObject callObjectMethod(const char *methodName, const char *signature, ...) const;
template <typename T>
static T callStaticMethod(const char *className, const char *methodName,
- const char *signature, ...);
- template <typename T>
- static T callStaticMethod(const char *className, const char *methodName);
+ const char *signature, ...)
+ {
+ assertJniPrimitiveType<T>();
+ QJniEnvironment env;
+ T res{};
+ jclass clazz = QJniObject::loadClass(className, env.jniEnv());
+ if (clazz) {
+ jmethodID id = getCachedMethodID(env.jniEnv(), clazz,
+ QJniObject::toBinaryEncClassName(className),
+ methodName, signature, true);
+ if (id) {
+ va_list args;
+ va_start(args, signature);
+ callStaticMethodForType<T>(env.jniEnv(), res, clazz, id, args);
+ va_end(args);
+ if (env.checkAndClearExceptions())
+ res = {};
+ }
+ }
+ return res;
+ }
+
+ template <>
+ void callStaticMethod<void>(const char *className, const char *methodName,
+ const char *signature, ...)
+ {
+ QJniEnvironment env;
+ jclass clazz = QJniObject::loadClass(className, env.jniEnv());
+ if (clazz) {
+ jmethodID id = getCachedMethodID(env.jniEnv(), clazz,
+ QJniObject::toBinaryEncClassName(className),
+ methodName, signature, true);
+ if (id) {
+ va_list args;
+ va_start(args, signature);
+ env->CallStaticVoidMethodV(clazz, id, args);
+ va_end(args);
+ env.checkAndClearExceptions();
+ }
+ }
+ }
+
template <typename T>
- static T callStaticMethod(jclass clazz, const char *methodName, const char *signature, ...);
+ static T callStaticMethod(const char *className, const char *methodName)
+ {
+ assertJniPrimitiveType<T>();
+ constexpr const char *signature = getTypeSignature<T>();
+ return callStaticMethod<T>(className, methodName, QByteArray(signature).prepend("()").constData());
+ }
+
+ template <>
+ void callStaticMethod<void>(const char *className, const char *methodName)
+ {
+ callStaticMethod<void>(className, methodName, "()V");
+ }
+
template <typename T>
- static T callStaticMethod(jclass clazz, const char *methodName);
+ static T callStaticMethod(jclass clazz, const char *methodName, const char *signature, ...)
+ {
+ assertJniPrimitiveType<T>();
+ QJniEnvironment env;
+ T res{};
+ if (clazz) {
+ jmethodID id = getMethodID(env.jniEnv(), clazz, methodName, signature, true);
+ if (id) {
+ va_list args;
+ va_start(args, signature);
+ callStaticMethodForType<T>(env.jniEnv(), res, clazz, id, args);
+ va_end(args);
+ if (env.checkAndClearExceptions())
+ res = {};
+ }
+ }
+ return res;
+ }
+
+ template <>
+ void callStaticMethod<void>(jclass clazz, const char *methodName,
+ const char *signature, ...)
+ {
+ QJniEnvironment env;
+ if (clazz) {
+ jmethodID id = getMethodID(env.jniEnv(), clazz, methodName, signature, true);
+ if (id) {
+ va_list args;
+ va_start(args, signature);
+ env->CallStaticVoidMethodV(clazz, id, args);
+ va_end(args);
+ env.checkAndClearExceptions();
+ }
+ }
+ }
+
+ template <typename T> static T callStaticMethod(jclass clazz, const char *methodName)
+ {
+ assertJniPrimitiveType<T>();
+ constexpr const char *signature = getTypeSignature<T>();
+ return callStaticMethod<T>(clazz, methodName, QByteArray(signature).prepend("()").constData());
+ }
+
+ template <>
+ void callStaticMethod<void>(jclass clazz, const char *methodName)
+ {
+ callStaticMethod<void>(clazz, methodName, "()V");
+ }
template <typename T>
- static QJniObject callStaticObjectMethod(const char *className, const char *methodName);
- static QJniObject callStaticObjectMethod(const char *className,
- const char *methodName,
+ static QJniObject callStaticObjectMethod(const char *className, const char *methodName)
+ {
+ assertJniObjectType<T>();
+ constexpr const char *signature = getTypeSignature<T>();
+ return callStaticObjectMethod(className, methodName, QByteArray(signature).prepend("()").constData());
+ }
+
+ static QJniObject callStaticObjectMethod(const char *className, const char *methodName,
const char *signature, ...);
template <typename T>
- static QJniObject callStaticObjectMethod(jclass clazz, const char *methodName);
- static QJniObject callStaticObjectMethod(jclass clazz,
- const char *methodName,
+ static QJniObject callStaticObjectMethod(jclass clazz, const char *methodName)
+ {
+ assertJniObjectType<T>();
+ constexpr const char *signature = getTypeSignature<T>();
+ return callStaticObjectMethod(clazz, methodName, QByteArray(signature).prepend("()").constData());
+ }
+
+ static QJniObject callStaticObjectMethod(jclass clazz, const char *methodName,
const char *signature, ...);
- template <typename T>
- T getField(const char *fieldName) const;
+ template <typename T> T getField(const char *fieldName) const
+ {
+ assertJniPrimitiveType<T>();
+ QJniEnvironment env;
+ T res{};
+ constexpr const char *signature = getTypeSignature<T>();
+ jfieldID id = getCachedFieldID(env.jniEnv(), fieldName, signature);
+ if (id) {
+ getFieldForType<T>(env.jniEnv(), res, object(), id);
+ if (env.checkAndClearExceptions())
+ res = {};
+ }
+ return res;
+ }
template <typename T>
- static T getStaticField(const char *className, const char *fieldName);
+ static T getStaticField(const char *className, const char *fieldName)
+ {
+ assertJniPrimitiveType<T>();
+ QJniEnvironment env;
+ jclass clazz = QJniObject::loadClass(className, env.jniEnv());
+ if (!clazz)
+ return 0;
+
+ constexpr const char *signature = getTypeSignature<T>();
+ jfieldID id = getCachedFieldID(env.jniEnv(), clazz,
+ QJniObject::toBinaryEncClassName(className),
+ fieldName,
+ signature, true);
+ if (!id)
+ return 0;
+
+ T res{};
+ getStaticFieldForType<T>(env.jniEnv(), res, clazz, id);
+ if (env.checkAndClearExceptions())
+ res = {};
+ return res;
+ }
+
template <typename T>
- static T getStaticField(jclass clazz, const char *fieldName);
+ static T getStaticField(jclass clazz, const char *fieldName)
+ {
+ assertJniPrimitiveType<T>();
+ QJniEnvironment env;
+ T res{};
+ constexpr const char *signature = getTypeSignature<T>();
+ jfieldID id = getFieldID(env.jniEnv(), clazz, fieldName, signature, true);
+ if (id) {
+ getStaticFieldForType<T>(env.jniEnv(), res, clazz, id);
+ if (env.checkAndClearExceptions())
+ res = {};
+ }
+ return res;
+ }
template <typename T>
- QJniObject getObjectField(const char *fieldName) const;
+ QJniObject getObjectField(const char *fieldName) const
+ {
+ assertJniObjectType<T>();
+ constexpr const char *signature = getTypeSignature<T>();
+ return getObjectField(fieldName, signature);
+ }
+
QJniObject getObjectField(const char *fieldName, const char *signature) const;
template <typename T>
- static QJniObject getStaticObjectField(const char *className, const char *fieldName);
- static QJniObject getStaticObjectField(const char *className,
- const char *fieldName,
- const char *signature);
- template <typename T>
+ static QJniObject getStaticObjectField(const char *className, const char *fieldName)
+ {
+ assertJniObjectType<T>();
+ constexpr const char *signature = getTypeSignature<T>();
+ return getStaticObjectField(className, fieldName, signature);
+ }
+
static QJniObject getStaticObjectField(const char *className,
const char *fieldName,
const char *signature);
template <typename T>
- static QJniObject getStaticObjectField(jclass clazz, const char *fieldName);
- static QJniObject getStaticObjectField(jclass clazz, const char *fieldName,
- const char *signature);
- template <typename T>
+ static QJniObject getStaticObjectField(jclass clazz, const char *fieldName)
+ {
+ assertJniObjectType<T>();
+ constexpr const char *signature = getTypeSignature<T>();
+ return getStaticObjectField(clazz, fieldName, signature);
+ }
+
static QJniObject getStaticObjectField(jclass clazz, const char *fieldName,
const char *signature);
+ template <typename T> void setField(const char *fieldName, T value)
+ {
+ assertJniType<T>();
+ QJniEnvironment env;
+ constexpr const char *signature = getTypeSignature<T>();
+ jfieldID id = getCachedFieldID(env.jniEnv(), fieldName, signature);
+ if (id) {
+ setFieldForType<T>(env, object(), id, value);
+ env.checkAndClearExceptions();
+ }
+ }
+
template <typename T>
- void setField(const char *fieldName, T value);
- template <typename T>
- void setField(const char *fieldName, const char *signature, T value);
+ void setField(const char *fieldName, const char *signature, T value)
+ {
+ assertJniType<T>();
+ QJniEnvironment env;
+ jfieldID id = getCachedFieldID(env.jniEnv(), fieldName, signature);
+ if (id) {
+ setFieldForType<T>(env, object(), id, value);
+ env.checkAndClearExceptions();
+ }
+ }
+
template <typename T>
- static void setStaticField(const char *className, const char *fieldName, T value);
+ static void setStaticField(const char *className, const char *fieldName, T value)
+ {
+ assertJniType<T>();
+ QJniEnvironment env;
+ jclass clazz = QJniObject::loadClass(className, env.jniEnv());
+ if (!clazz)
+ return;
+
+ constexpr const char *signature = getTypeSignature<T>();
+ jfieldID id = getCachedFieldID(env.jniEnv(), clazz, className, fieldName,
+ signature, true);
+ if (!id)
+ return;
+
+ setStaticFieldForType<T>(env, clazz, id, value);
+ env.checkAndClearExceptions();
+ }
+
template <typename T>
static void setStaticField(const char *className, const char *fieldName,
- const char *signature, T value);
+ const char *signature, T value)
+ {
+ assertJniType<T>();
+ QJniEnvironment env;
+ jclass clazz = QJniObject::loadClass(className, env.jniEnv());
+
+ if (!clazz)
+ return;
+
+ jfieldID id = getCachedFieldID(env.jniEnv(), clazz, className, fieldName,
+ signature, true);
+ if (id) {
+ setStaticFieldForType<T>(env, clazz, id, value);
+ env.checkAndClearExceptions();
+ }
+ }
+
template <typename T>
static void setStaticField(jclass clazz, const char *fieldName,
- const char *signature, T value);
+ const char *signature, T value)
+ {
+ assertJniType<T>();
+ QJniEnvironment env;
+ jfieldID id = getFieldID(env.jniEnv(), clazz, fieldName, signature, true);
+
+ if (id) {
+ setStaticFieldForType<T>(env, clazz, id, value);
+ env.checkAndClearExceptions();
+ }
+ }
template <typename T>
- static void setStaticField(jclass clazz, const char *fieldName, T value);
+ static void setStaticField(jclass clazz, const char *fieldName, T value)
+ {
+ assertJniType<T>();
+ QJniEnvironment env;
+ constexpr const char *signature = getTypeSignature<T>();
+ jfieldID id = getFieldID(env.jniEnv(), clazz, fieldName, signature, true);
+ if (id) {
+ setStaticFieldForType<T>(env, clazz, id, value);
+ env.checkAndClearExceptions();
+ }
+ }
static QJniObject fromString(const QString &string);
QString toString() const;
@@ -153,39 +440,47 @@ public:
// This function takes ownership of the jobject and releases the local ref. before returning.
static QJniObject fromLocalRef(jobject lref);
- template <typename T> QJniObject &operator=(T obj);
+ template <typename T> QJniObject &operator=(T obj)
+ {
+ assertJniType<T>();
+ assign(static_cast<T>(obj));
+ return *this;
+ }
private:
struct QVaListPrivate { operator va_list &() const { return m_args; } va_list &m_args; };
-
QJniObject(const char *className, const char *signature, const QVaListPrivate &args);
QJniObject(jclass clazz, const char *signature, const QVaListPrivate &args);
- template <typename T>
- T callMethodV(const char *methodName, const char *signature, va_list args) const;
- QJniObject callObjectMethodV(const char *methodName,
- const char *signature,
+ static jclass loadClass(const QByteArray &className, JNIEnv *env, bool binEncoded = false);
+ static QByteArray toBinaryEncClassName(const QByteArray &className);
+ static QJniObject getCleanJniObject(jobject obj);
+
+ static jfieldID getCachedFieldID(JNIEnv *env, jclass clazz, const QByteArray &className,
+ const char *name, const char *signature,
+ bool isStatic = false);
+ jfieldID getCachedFieldID(JNIEnv *env, const char *name, const char *signature,
+ bool isStatic = false) const;
+ static jmethodID getCachedMethodID(JNIEnv *env, jclass clazz, const QByteArray &className,
+ const char *name, const char *signature,
+ bool isStatic = false);
+ jmethodID getCachedMethodID(JNIEnv *env, const char *name, const char *signature,
+ bool isStatic = false) const;
+
+ static jfieldID getFieldID(JNIEnv *env, jclass clazz, const char *name,
+ const char *signature, bool isStatic = false);
+ static jmethodID getMethodID(JNIEnv *env, jclass clazz, const char *name,
+ const char *signature, bool isStatic = false);
+
+ void callVoidMethodV(JNIEnv *env, jmethodID id, va_list args) const;
+ QJniObject callObjectMethodV(const char *methodName, const char *signature,
va_list args) const;
- template <typename T>
- static T callStaticMethodV(const char *className,
- const char *methodName,
- const char *signature,
- va_list args);
- template <typename T>
- static T callStaticMethodV(jclass clazz,
- const char *methodName,
- const char *signature,
- va_list args);
- static QJniObject callStaticObjectMethodV(const char *className,
- const char *methodName,
- const char *signature,
- va_list args);
+ static QJniObject callStaticObjectMethodV(const char *className, const char *methodName,
+ const char *signature, va_list args);
- static QJniObject callStaticObjectMethodV(jclass clazz,
- const char *methodName,
- const char *signature,
- va_list args);
+ static QJniObject callStaticObjectMethodV(jclass clazz, const char *methodName,
+ const char *signature, va_list args);
bool isSameObject(jobject obj) const;
bool isSameObject(const QJniObject &other) const;
@@ -195,6 +490,249 @@ private:
friend bool operator==(const QJniObject &, const QJniObject &);
friend bool operator!=(const QJniObject&, const QJniObject&);
+ template<bool flag = false>
+ static void staticAssertTypeMismatch()
+ {
+ static_assert(flag, "The used type is not supported by this template call. "
+ "Use a JNI based type instead.");
+ }
+
+ template<typename T>
+ static constexpr bool isJniPrimitiveType()
+ {
+ if constexpr(!std::is_same<T, jboolean>::value
+ && !std::is_same<T, jbyte>::value
+ && !std::is_same<T, jchar>::value
+ && !std::is_same<T, jshort>::value
+ && !std::is_same<T, jint>::value
+ && !std::is_same<T, jlong>::value
+ && !std::is_same<T, jfloat>::value
+ && !std::is_same<T, jdouble>::value) {
+ return false;
+ }
+
+ return true;
+ }
+
+ template<typename T>
+ static constexpr void assertJniPrimitiveType()
+ {
+ if constexpr(!isJniPrimitiveType<T>())
+ staticAssertTypeMismatch();
+ }
+
+ template<typename T>
+ static constexpr void assertJniObjectType()
+ {
+ if constexpr(!std::is_convertible<T, jobject>::value)
+ staticAssertTypeMismatch();
+ }
+
+ template<typename T>
+ static constexpr void assertJniType()
+ {
+ if constexpr(!isJniPrimitiveType<T>() && !std::is_convertible<T, jobject>::value)
+ staticAssertTypeMismatch();
+ }
+
+ template<typename T>
+ static constexpr const char* getTypeSignature()
+ {
+ if constexpr(std::is_same<T, jobject>::value)
+ return "Ljava/lang/Object;";
+ else if constexpr(std::is_same<T, jclass>::value)
+ return "Ljava/lang/Class;";
+ else if constexpr(std::is_same<T, jstring>::value)
+ return "Ljava/lang/String;";
+ else if constexpr(std::is_same<T, jobjectArray>::value)
+ return "[Ljava/lang/Object;";
+ else if constexpr(std::is_same<T, jthrowable>::value)
+ return "Ljava/lang/Throwable;";
+ else if constexpr(std::is_same<T, jbooleanArray>::value)
+ return "[Z";
+ else if constexpr(std::is_same<T, jbyteArray>::value)
+ return "[B";
+ else if constexpr(std::is_same<T, jshortArray>::value)
+ return "[S";
+ else if constexpr(std::is_same<T, jintArray>::value)
+ return "[I";
+ else if constexpr(std::is_same<T, jlongArray>::value)
+ return "[J";
+ else if constexpr(std::is_same<T, jfloatArray>::value)
+ return "[F";
+ else if constexpr(std::is_same<T, jdoubleArray>::value)
+ return "[D";
+ else if constexpr(std::is_same<T, jcharArray>::value)
+ return "[C";
+ else if constexpr(std::is_same<T, jboolean>::value)
+ return "Z";
+ else if constexpr(std::is_same<T, jbyte>::value)
+ return "B";
+ else if constexpr(std::is_same<T, jchar>::value)
+ return "C";
+ else if constexpr(std::is_same<T, jshort>::value)
+ return "S";
+ else if constexpr(std::is_same<T, jint>::value)
+ return "I";
+ else if constexpr(std::is_same<T, jlong>::value)
+ return "J";
+ else if constexpr(std::is_same<T, jfloat>::value)
+ return "F";
+ else if constexpr(std::is_same<T, jdouble>::value)
+ return "D";
+ else
+ staticAssertTypeMismatch();
+ }
+
+ template<typename T>
+ static constexpr void callMethodForType(JNIEnv *env, T &res, jobject obj,
+ jmethodID id, va_list args)
+ {
+ if constexpr(std::is_same<T, jboolean>::value)
+ res = env->CallBooleanMethodV(obj, id, args);
+ else if constexpr(std::is_same<T, jbyte>::value)
+ res = env->CallByteMethodV(obj, id, args);
+ else if constexpr(std::is_same<T, jchar>::value)
+ res = env->CallCharMethodV(obj, id, args);
+ else if constexpr(std::is_same<T, jshort>::value)
+ res = env->CallShortMethodV(obj, id, args);
+ else if constexpr(std::is_same<T, jint>::value)
+ res = env->CallIntMethodV(obj, id, args);
+ else if constexpr(std::is_same<T, jlong>::value)
+ res = env->CallLongMethodV(obj, id, args);
+ else if constexpr(std::is_same<T, jfloat>::value)
+ res = env->CallFloatMethodV(obj, id, args);
+ else if constexpr(std::is_same<T, jdouble>::value)
+ res = env->CallDoubleMethodV(obj, id, args);
+ else
+ staticAssertTypeMismatch();
+ }
+
+ template<typename T>
+ static constexpr void callStaticMethodForType(JNIEnv *env, T &res, jclass clazz,
+ jmethodID id, va_list args)
+ {
+ if constexpr(std::is_same<T, jboolean>::value)
+ res = env->CallStaticBooleanMethodV(clazz, id, args);
+ else if constexpr(std::is_same<T, jbyte>::value)
+ res = env->CallStaticByteMethodV(clazz, id, args);
+ else if constexpr(std::is_same<T, jchar>::value)
+ res = env->CallStaticCharMethodV(clazz, id, args);
+ else if constexpr(std::is_same<T, jshort>::value)
+ res = env->CallStaticShortMethodV(clazz, id, args);
+ else if constexpr(std::is_same<T, jint>::value)
+ res = env->CallStaticIntMethodV(clazz, id, args);
+ else if constexpr(std::is_same<T, jlong>::value)
+ res = env->CallStaticLongMethodV(clazz, id, args);
+ else if constexpr(std::is_same<T, jfloat>::value)
+ res = env->CallStaticFloatMethodV(clazz, id, args);
+ else if constexpr(std::is_same<T, jdouble>::value)
+ res = env->CallStaticDoubleMethodV(clazz, id, args);
+ else
+ staticAssertTypeMismatch();
+ }
+
+ template<typename T>
+ static constexpr void getFieldForType(JNIEnv *env, T &res, jobject obj,
+ jfieldID id)
+ {
+ if constexpr(std::is_same<T, jboolean>::value)
+ res = env->GetBooleanField(obj, id);
+ else if constexpr(std::is_same<T, jbyte>::value)
+ res = env->GetByteField(obj, id);
+ else if constexpr(std::is_same<T, jchar>::value)
+ res = env->GetCharField(obj, id);
+ else if constexpr(std::is_same<T, jshort>::value)
+ res = env->GetShortField(obj, id);
+ else if constexpr(std::is_same<T, jint>::value)
+ res = env->GetIntField(obj, id);
+ else if constexpr(std::is_same<T, jlong>::value)
+ res = env->GetLongField(obj, id);
+ else if constexpr(std::is_same<T, jfloat>::value)
+ res = env->GetFloatField(obj, id);
+ else if constexpr(std::is_same<T, jdouble>::value)
+ res = env->GetDoubleField(obj, id);
+ else
+ staticAssertTypeMismatch();
+ }
+
+ template<typename T>
+ static constexpr void getStaticFieldForType(JNIEnv *env, T &res, jclass clazz,
+ jfieldID id)
+ {
+ if constexpr(std::is_same<T, jboolean>::value)
+ res = env->GetStaticBooleanField(clazz, id);
+ else if constexpr(std::is_same<T, jbyte>::value)
+ res = env->GetStaticByteField(clazz, id);
+ else if constexpr(std::is_same<T, jchar>::value)
+ res = env->GetStaticCharField(clazz, id);
+ else if constexpr(std::is_same<T, jshort>::value)
+ res = env->GetStaticShortField(clazz, id);
+ else if constexpr(std::is_same<T, jint>::value)
+ res = env->GetStaticIntField(clazz, id);
+ else if constexpr(std::is_same<T, jlong>::value)
+ res = env->GetStaticLongField(clazz, id);
+ else if constexpr(std::is_same<T, jfloat>::value)
+ res = env->GetStaticFloatField(clazz, id);
+ else if constexpr(std::is_same<T, jdouble>::value)
+ res = env->GetStaticDoubleField(clazz, id);
+ else
+ staticAssertTypeMismatch();
+ }
+
+ template<typename T>
+ static constexpr void setFieldForType(JNIEnv *env, jobject obj,
+ jfieldID id, T value)
+ {
+ if constexpr(std::is_same<T, jboolean>::value)
+ env->SetBooleanField(obj, id, value);
+ else if constexpr(std::is_same<T, jbyte>::value)
+ env->SetByteField(obj, id, value);
+ else if constexpr(std::is_same<T, jchar>::value)
+ env->SetCharField(obj, id, value);
+ else if constexpr(std::is_same<T, jshort>::value)
+ env->SetShortField(obj, id, value);
+ else if constexpr(std::is_same<T, jint>::value)
+ env->SetIntField(obj, id, value);
+ else if constexpr(std::is_same<T, jlong>::value)
+ env->SetLongField(obj, id, value);
+ else if constexpr(std::is_same<T, jfloat>::value)
+ env->SetFloatField(obj, id, value);
+ else if constexpr(std::is_same<T, jdouble>::value)
+ env->SetDoubleField(obj, id, value);
+ else if constexpr(std::is_convertible<T, jobject>::value)
+ env->SetObjectField(obj, id, value);
+ else
+ staticAssertTypeMismatch();
+ }
+
+ template<typename T>
+ static constexpr void setStaticFieldForType(JNIEnv *env, jclass clazz,
+ jfieldID id, T value)
+ {
+ if constexpr(std::is_same<T, jboolean>::value)
+ env->SetStaticBooleanField(clazz, id, value);
+ else if constexpr(std::is_same<T, jbyte>::value)
+ env->SetStaticByteField(clazz, id, value);
+ else if constexpr(std::is_same<T, jchar>::value)
+ env->SetStaticCharField(clazz, id, value);
+ else if constexpr(std::is_same<T, jshort>::value)
+ env->SetStaticShortField(clazz, id, value);
+ else if constexpr(std::is_same<T, jint>::value)
+ env->SetStaticIntField(clazz, id, value);
+ else if constexpr(std::is_same<T, jlong>::value)
+ env->SetStaticLongField(clazz, id, value);
+ else if constexpr(std::is_same<T, jfloat>::value)
+ env->SetStaticFloatField(clazz, id, value);
+ else if constexpr(std::is_same<T, jdouble>::value)
+ env->SetStaticDoubleField(clazz, id, value);
+ else if constexpr(std::is_convertible<T, jobject>::value)
+ env->SetStaticObjectField(clazz, id, value);
+ else
+ staticAssertTypeMismatch();
+ }
+
+ friend QJniObjectPrivate;
QSharedPointer<QJniObjectPrivate> d;
};
@@ -210,4 +748,6 @@ inline bool operator!=(const QJniObject &obj1, const QJniObject &obj2)
QT_END_NAMESPACE
+#endif
+
#endif // QJNIOBJECT_H