diff --git a/src/corelib/kernel/qjnienvironment.h b/src/corelib/kernel/qjnienvironment.h index 0a32b19c8e1..6cc8693227d 100644 --- a/src/corelib/kernel/qjnienvironment.h +++ b/src/corelib/kernel/qjnienvironment.h @@ -52,6 +52,16 @@ public: bool registerNativeMethods(const char *className, const JNINativeMethod methods[], int size); bool registerNativeMethods(jclass clazz, const JNINativeMethod methods[], int size); + bool registerNativeMethods(const char *className, std::initializer_list methods) + { + return registerNativeMethods(className, std::data(methods), methods.size()); + } + + bool registerNativeMethods(jclass clazz, std::initializer_list methods) + { + return registerNativeMethods(clazz, std::data(methods), methods.size()); + } + #if QT_DEPRECATED_SINCE(6, 2) // ### Qt 7: remove QT_DEPRECATED_VERSION_X_6_2("Use the overload with a const JNINativeMethod[] instead.") diff --git a/src/corelib/kernel/qjnitypes.h b/src/corelib/kernel/qjnitypes.h index e5306f3c545..0ebc1a6bc97 100644 --- a/src/corelib/kernel/qjnitypes.h +++ b/src/corelib/kernel/qjnitypes.h @@ -274,6 +274,18 @@ static constexpr auto constructorSignature() return methodSignature(); } +template +static constexpr auto nativeMethodSignature(Ret (*)(JNIEnv *, jobject, Args...)) +{ + return methodSignature(); +} + +template +static constexpr auto nativeMethodSignature(Ret (*)(JNIEnv *, jclass, Args...)) +{ + return methodSignature(); +} + // A generic thin wrapper around jobject, convertible to jobject. // We need this as a baseclass so that QJniObject can be implicitly // constructed from the various subclasses - we can't provide an @@ -303,6 +315,18 @@ constexpr auto QtJniTypes::typeSignature() \ return QtJniTypes::String(Signature); \ } \ +#define Q_JNI_DECLARE_NATIVE_METHOD(Method) \ +namespace QtJniMethods { \ +static constexpr auto Method##_signature = \ + QtJniTypes::nativeMethodSignature(Method); \ +static const JNINativeMethod Method##_method = { \ + #Method, Method##_signature.data(), \ + reinterpret_cast(Method) \ +}; \ +} \ + +#define Q_JNI_NATIVE_METHOD(Method) QtJniMethods::Method##_method + QT_END_NAMESPACE #endif diff --git a/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp b/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp index bcc5556d607..f699d6816a7 100644 --- a/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp +++ b/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp @@ -98,12 +98,14 @@ static void callbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value) Q_UNUSED(env) registerNativesString = QJniObject(value).toString(); } +Q_JNI_DECLARE_NATIVE_METHOD(callbackFromJava); static void callbackFromJavaNoCtor(JNIEnv *env, jobject /*thiz*/, jstring value) { Q_UNUSED(env) registerNativesString = QJniObject(value).toString(); } +Q_JNI_DECLARE_NATIVE_METHOD(callbackFromJavaNoCtor); void tst_QJniEnvironment::registerNativeMethods() { @@ -111,11 +113,9 @@ void tst_QJniEnvironment::registerNativeMethods() QJniEnvironment env; { - const JNINativeMethod methods[] { - {"callbackFromJava", "(Ljava/lang/String;)V", reinterpret_cast(callbackFromJava)} - }; - - QVERIFY(env.registerNativeMethods(javaTestClass, methods, 1)); + QVERIFY(env.registerNativeMethods(javaTestClass, { + Q_JNI_NATIVE_METHOD(callbackFromJava) + })); QJniObject::callStaticMethod(javaTestClass, "appendJavaToString", @@ -127,10 +127,9 @@ void tst_QJniEnvironment::registerNativeMethods() // No default constructor in class { - const JNINativeMethod methods[] {{"callbackFromJavaNoCtor", "(Ljava/lang/String;)V", - reinterpret_cast(callbackFromJavaNoCtor)}}; - - QVERIFY(env.registerNativeMethods(javaTestClassNoCtor, methods, 1)); + QVERIFY(env.registerNativeMethods(javaTestClassNoCtor, { + Q_JNI_NATIVE_METHOD(callbackFromJavaNoCtor) + })); QJniObject::callStaticMethod(javaTestClassNoCtor, "appendJavaToString", @@ -146,17 +145,16 @@ static void intCallbackFromJava(JNIEnv *env, jobject /*thiz*/, jint value) Q_UNUSED(env) registerNativeInteger = static_cast(value); } +Q_JNI_DECLARE_NATIVE_METHOD(intCallbackFromJava); void tst_QJniEnvironment::registerNativeMethodsByJclass() { - const JNINativeMethod methods[] { - { "intCallbackFromJava", "(I)V", reinterpret_cast(intCallbackFromJava) } - }; - QJniEnvironment env; jclass clazz = env.findClass(javaTestClass); QVERIFY(clazz != 0); - QVERIFY(env.registerNativeMethods(clazz, methods, 1)); + QVERIFY(env.registerNativeMethods(clazz, { + Q_JNI_NATIVE_METHOD(intCallbackFromJava) + })); QCOMPARE(registerNativeInteger, 0);