diff options
3 files changed, 103 insertions, 0 deletions
diff --git a/src/corelib/kernel/qjnitypes.h b/src/corelib/kernel/qjnitypes.h index bbe0bb2cc7..73b5db297c 100644 --- a/src/corelib/kernel/qjnitypes.h +++ b/src/corelib/kernel/qjnitypes.h @@ -367,6 +367,20 @@ static const JNINativeMethod Method##_method = { \ #define Q_JNI_NATIVE_METHOD(Method) QtJniMethods::Method##_method +#define Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(...) \ + QT_OVERLOADED_MACRO(QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE, __VA_ARGS__) \ + +#define QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE_2(Method, Name) \ + static inline constexpr auto Method##_signature = QtJniTypes::nativeMethodSignature(Method); \ + static inline const JNINativeMethod Method##_method = { \ + #Name, Method##_signature.data(), reinterpret_cast<void *>(Method) \ + }; + +#define QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE_1(Method) \ + QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE_2(Method, Method) \ + +#define Q_JNI_NATIVE_SCOPED_METHOD(Method, Scope) Scope::Method##_method + QT_END_NAMESPACE #endif diff --git a/tests/auto/corelib/kernel/qjnienvironment/testdata/src/org/qtproject/qt/android/testdata/QtJniEnvironmentTestClass.java b/tests/auto/corelib/kernel/qjnienvironment/testdata/src/org/qtproject/qt/android/testdata/QtJniEnvironmentTestClass.java index 342342c548..984307d57d 100644 --- a/tests/auto/corelib/kernel/qjnienvironment/testdata/src/org/qtproject/qt/android/testdata/QtJniEnvironmentTestClass.java +++ b/tests/auto/corelib/kernel/qjnienvironment/testdata/src/org/qtproject/qt/android/testdata/QtJniEnvironmentTestClass.java @@ -7,6 +7,9 @@ public class QtJniEnvironmentTestClass { private static native void callbackFromJava(String message); private static native void namedCallbackFromJava(String message); + private static native void memberCallbackFromJava(String message); + private static native void namedMemberCallbackFromJava(String message); + private static native void namespaceCallbackFromJava(String message); private static native void intCallbackFromJava(int value); public final int INT_FIELD = 123; @@ -24,6 +27,21 @@ public class QtJniEnvironmentTestClass namedCallbackFromJava("From Java (named): " + message); } + public static void memberAppendJavaToString(String message) + { + memberCallbackFromJava("From Java (member): " + message); + } + + public static void namedMemberAppendJavaToString(String message) + { + namedMemberCallbackFromJava("From Java (named member): " + message); + } + + public static void namespaceAppendJavaToString(String message) + { + namespaceCallbackFromJava("From Java (namespace): " + message); + } + public static void convertToInt(String message) { intCallbackFromJava(Integer.parseInt(message)); diff --git a/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp b/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp index 4809505f47..da72b6d32b 100644 --- a/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp +++ b/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp @@ -115,6 +115,34 @@ static void callbackFromJavaNoCtor(JNIEnv *env, jobject /*thiz*/, jstring value) } Q_DECLARE_JNI_NATIVE_METHOD(callbackFromJavaNoCtor); +class CallbackClass { +public: + static void memberCallbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value) + { + Q_UNUSED(env) + registerNativesString = QJniObject(value).toString(); + } + Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(memberCallbackFromJava) + + static void tediouslyLongNamed_memberCallbackFromJava(JNIEnv *env, jobject /*thiz*/, + jstring value) + { + Q_UNUSED(env) + registerNativesString = QJniObject(value).toString(); + } + Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(tediouslyLongNamed_memberCallbackFromJava, + namedMemberCallbackFromJava) +}; + +namespace CallbackNamespace { + static void namespaceCallbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value) + { + Q_UNUSED(env) + registerNativesString = QJniObject(value).toString(); + } + Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(namespaceCallbackFromJava) +} + void tst_QJniEnvironment::registerNativeMethods() { QJniObject QtString = QJniObject::fromString(registerNativesString); @@ -147,6 +175,49 @@ void tst_QJniEnvironment::registerNativeMethods() QVERIFY(registerNativesString == QStringLiteral("From Java (named): Qt")); } + // Static class member as callback + { + QVERIFY(env.registerNativeMethods(javaTestClass, { + Q_JNI_NATIVE_SCOPED_METHOD(memberCallbackFromJava, CallbackClass) + })); + + QJniObject::callStaticMethod<void>(javaTestClass, + "memberAppendJavaToString", + "(Ljava/lang/String;)V", + QtString.object<jstring>()); + QTest::qWait(200); + QVERIFY(registerNativesString == QStringLiteral("From Java (member): Qt")); + } + + // Static named class member as callback + { + QVERIFY(env.registerNativeMethods(javaTestClass, { + Q_JNI_NATIVE_SCOPED_METHOD(tediouslyLongNamed_memberCallbackFromJava, + CallbackClass) + })); + + QJniObject::callStaticMethod<void>(javaTestClass, + "namedMemberAppendJavaToString", + "(Ljava/lang/String;)V", + QtString.object<jstring>()); + QTest::qWait(200); + QVERIFY(registerNativesString == QStringLiteral("From Java (named member): Qt")); + } + + // Function generally just in namespace as callback + { + QVERIFY(env.registerNativeMethods(javaTestClass, { + Q_JNI_NATIVE_SCOPED_METHOD(namespaceCallbackFromJava, CallbackNamespace) + })); + + QJniObject::callStaticMethod<void>(javaTestClass, + "namespaceAppendJavaToString", + "(Ljava/lang/String;)V", + QtString.object<jstring>()); + QTest::qWait(200); + QVERIFY(registerNativesString == QStringLiteral("From Java (namespace): Qt")); + } + // No default constructor in class { QVERIFY(env.registerNativeMethods(javaTestClassNoCtor, { |