summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2022-05-24 17:20:15 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2022-05-27 22:27:13 +0200
commit31f98957cf5c061f868588ef81059a907c9d30ad (patch)
tree0d6487bbed38198b4f49ee4776473bd0f813a730 /src
parent9614f4d434474fe7dcca752b3f72a56f2d382230 (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.h2
-rw-r--r--src/corelib/kernel/qjniobject.h8
-rw-r--r--src/corelib/kernel/qjnitypes.h39
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); \