diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2022-05-24 17:20:15 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2022-05-27 22:27:13 +0200 |
commit | 31f98957cf5c061f868588ef81059a907c9d30ad (patch) | |
tree | 0d6487bbed38198b4f49ee4776473bd0f813a730 /src | |
parent | 9614f4d434474fe7dcca752b3f72a56f2d382230 (diff) |
Add compile-time generation of JNI class names
As with method signatures, register class names using template function
specialization in the QtJniTypes namespace, and then declare C++ types
as JNI classes with a class name string. Such classes implicitly get
registered as JNI types as well.
Add a QJniObject construct method (since C++ constructors that are
templates cannot be explicitly instantiated with a type), and a
QJniEnvironment::findClass overload.
Add test coverage, also for the recently added macros for native
methods.
As a drive-by, change the name of the Q_JNI_DECLARE_NATIVE_METHOD
macro to Q_DECLARE_JNI_NATIVE_METHOD for consistency.
Change-Id: Ic19562d78da726f202b3bdf4e9354e8ad24d8bd9
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qjnienvironment.h | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qjniobject.h | 8 | ||||
-rw-r--r-- | src/corelib/kernel/qjnitypes.h | 39 |
3 files changed, 47 insertions, 2 deletions
diff --git a/src/corelib/kernel/qjnienvironment.h b/src/corelib/kernel/qjnienvironment.h index 6cc8693227..f7ffa836c2 100644 --- a/src/corelib/kernel/qjnienvironment.h +++ b/src/corelib/kernel/qjnienvironment.h @@ -24,6 +24,8 @@ public: JNIEnv &operator*() const; JNIEnv *jniEnv() const; jclass findClass(const char *className); + template<typename Class> + jclass findClass() { return findClass(QtJniTypes::className<Class>().data()); } jmethodID findMethod(jclass clazz, const char *methodName, const char *signature); template<typename ...Args> jmethodID findMethod(jclass clazz, const char *methodName) { diff --git a/src/corelib/kernel/qjniobject.h b/src/corelib/kernel/qjniobject.h index bbaa6ee70c..3c7ca13ff2 100644 --- a/src/corelib/kernel/qjniobject.h +++ b/src/corelib/kernel/qjniobject.h @@ -45,6 +45,14 @@ public: inline QJniObject(QtJniTypes::Object wrapper) noexcept : QJniObject(jobject(wrapper)) {} ~QJniObject(); + template<typename Class, typename ...Args> + static inline QJniObject construct(Args &&...args) + { + return QJniObject(QtJniTypes::className<Class>().data(), + QtJniTypes::constructorSignature<Args...>().data(), + std::forward<Args>(args)...); + } + jobject object() const; template <typename T> T object() const { diff --git a/src/corelib/kernel/qjnitypes.h b/src/corelib/kernel/qjnitypes.h index 0ebc1a6bc9..ecb8ae02f9 100644 --- a/src/corelib/kernel/qjnitypes.h +++ b/src/corelib/kernel/qjnitypes.h @@ -214,6 +214,21 @@ constexpr auto typeSignature() staticAssertTypeMismatch(); } +template<bool flag = false> +static void staticAssertClassNotRegistered() +{ + static_assert(flag, "Class not registered, use Q_DECLARE_JNI_CLASS"); +} + +template<typename T> +constexpr auto className() +{ + if constexpr(std::is_same<T, jstring>::value) + return String("java/lang/String"); + else + staticAssertClassNotRegistered(); +} + template<typename T> static constexpr bool isPrimitiveType() { @@ -298,13 +313,17 @@ struct Object } // namespace QtJniTypes -#define Q_DECLARE_JNI_TYPE(Type, Signature) \ +#define Q_DECLARE_JNI_TYPE_HELPER(Type) \ namespace QtJniTypes { \ struct Type : Object \ { \ constexpr Type(jobject o) noexcept : Object{o} {} \ }; \ } \ + + +#define Q_DECLARE_JNI_TYPE(Type, Signature) \ +Q_DECLARE_JNI_TYPE_HELPER(Type) \ template<> \ constexpr auto QtJniTypes::typeSignature<QtJniTypes::Type>() \ { \ @@ -315,7 +334,23 @@ constexpr auto QtJniTypes::typeSignature<QtJniTypes::Type>() \ return QtJniTypes::String(Signature); \ } \ -#define Q_JNI_DECLARE_NATIVE_METHOD(Method) \ +#define Q_DECLARE_JNI_CLASS(Type, Signature) \ +Q_DECLARE_JNI_TYPE_HELPER(Type) \ +template<> \ +constexpr auto QtJniTypes::className<QtJniTypes::Type>() \ +{ \ + return QtJniTypes::String(Signature); \ +} \ +template<> \ +constexpr auto QtJniTypes::typeSignature<QtJniTypes::Type>() \ +{ \ + return QtJniTypes::String("L") \ + + QtJniTypes::String(Signature) \ + + QtJniTypes::String(";"); \ +} \ + + +#define Q_DECLARE_JNI_NATIVE_METHOD(Method) \ namespace QtJniMethods { \ static constexpr auto Method##_signature = \ QtJniTypes::nativeMethodSignature(Method); \ |