Add support for scoped JNI callbacks
This commit adds macros for declaring scoped native callbacks which are in namespace or for example defined as static class member variables. The existing macros don't allow this as they use QtJniMethods namespace and the introduced callbacks' namespaces are not enclosed in that namespace, yielding a compilation error. Change-Id: I754560bea7e9a1b57c2661d1ee7236e78db39ba1 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit c5caab1f150dadc51219f3bbfb8d4fee7f23703f) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
49dd11fe34
commit
d940c69884
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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, {
|
||||
|
Loading…
x
Reference in New Issue
Block a user