Add a const JNINativeMethod[] overload for registerNativeMethods()

The JNI interface expects a const JNINativeMethod[] and our wrapper
takes a non-const. Also, this was causing refactoring of exisisting code
with a const JNINativeMethod[] to fail because the call expects a
non-const.

Change-Id: If790c401650cb33fe31f93bafe41aab7714488e9
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Assam Boudjelthia 2021-05-06 17:18:31 +03:00
parent 6d72896d0c
commit 78ed8034d2
4 changed files with 51 additions and 10 deletions

View File

@ -97,8 +97,9 @@ static void fromJavaTwo(JNIEnv *env, jobject thiz, jint x)
void foo()
{
// register the native methods first, ideally it better be done with the app start
JNINativeMethod methods[] {{"callNativeOne", "(I)V", reinterpret_cast<void *>(fromJavaOne)},
{"callNativeTwo", "(I)V", reinterpret_cast<void *>(fromJavaTwo)}};
const JNINativeMethod methods[] =
{{"callNativeOne", "(I)V", reinterpret_cast<void *>(fromJavaOne)},
{"callNativeTwo", "(I)V", reinterpret_cast<void *>(fromJavaTwo)}};
QJniEnvironment env;
env.registerNativeMethods("my/java/project/FooJavaClass", methods, 2);

View File

@ -268,7 +268,7 @@ JavaVM *QJniEnvironment::javaVM()
}
/*!
\fn bool QJniEnvironment::registerNativeMethods(const char *className, JNINativeMethod methods[], int size)
\fn bool QJniEnvironment::registerNativeMethods(const char *className, const JNINativeMethod methods[], int size)
Registers the Java methods in the array \a methods of size \a size, each of
which can call native C++ functions from class \a className. These methods
@ -284,13 +284,15 @@ JavaVM *QJniEnvironment::javaVM()
\endlist
\code
JNINativeMethod methods[] {{"callNativeOne", "(I)V", reinterpret_cast<void *>(fromJavaOne)},
{"callNativeTwo", "(I)V", reinterpret_cast<void *>(fromJavaTwo)}};
const JNINativeMethod methods[] =
{{"callNativeOne", "(I)V", reinterpret_cast<void *>(fromJavaOne)},
{"callNativeTwo", "(I)V", reinterpret_cast<void *>(fromJavaTwo)}};
QJniEnvironment env;
env.registerNativeMethods("org/qtproject/android/TestJavaClass", methods, 2);
\endcode
*/
bool QJniEnvironment::registerNativeMethods(const char *className, JNINativeMethod methods[], int size)
bool QJniEnvironment::registerNativeMethods(const char *className, const JNINativeMethod methods[],
int size)
{
QJniObject classObject(className);
@ -299,6 +301,37 @@ bool QJniEnvironment::registerNativeMethods(const char *className, JNINativeMeth
return registerNativeMethods(classObject.objectClass(), methods, size);
}
/*!
\overload
\obsolete Use the overload with a const JNINativeMethod[] instead.
Registers the Java methods in the array \a methods of size \a size, each of
which can call native C++ functions from class \a className. These methods
must be registered before any attempt to call them.
Returns \c true if the registration is successful, otherwise \c false.
Each element in the methods array consists of:
\list
\li The Java method name
\li Method signature
\li The C++ functions that will be executed
\endlist
\code
JNINativeMethod methods[] = {{"callNativeOne", "(I)V", reinterpret_cast<void *>(fromJavaOne)},
{"callNativeTwo", "(I)V", reinterpret_cast<void *>(fromJavaTwo)}};
QJniEnvironment env;
env.registerNativeMethods("org/qtproject/android/TestJavaClass", methods, 2);
\endcode
*/
#if QT_DEPRECATED_SINCE(6, 2)
bool QJniEnvironment::registerNativeMethods(const char *className, JNINativeMethod methods[],
int size)
{
return registerNativeMethods(className, const_cast<const JNINativeMethod*>(methods), size);
}
#endif
/*!
\overload
@ -312,7 +345,8 @@ bool QJniEnvironment::registerNativeMethods(const char *className, JNINativeMeth
env.registerNativeMethods(clazz, methods, 2);
\endcode
*/
bool QJniEnvironment::registerNativeMethods(jclass clazz, JNINativeMethod methods[], int size)
bool QJniEnvironment::registerNativeMethods(jclass clazz, const JNINativeMethod methods[],
int size)
{
if (d->jniEnv->RegisterNatives(clazz, methods, size) < 0) {
checkAndClearExceptions();

View File

@ -62,8 +62,14 @@ public:
jmethodID findMethod(jclass clazz, const char *methodName, const char *signature);
jmethodID findStaticMethod(jclass clazz, const char *methodName, const char *signature);
static JavaVM *javaVM();
bool registerNativeMethods(const char *className, const JNINativeMethod methods[], int size);
bool registerNativeMethods(jclass clazz, const JNINativeMethod methods[], int size);
#if QT_DEPRECATED_SINCE(6, 2)
// ### Qt 7: remove
QT_DEPRECATED_VERSION_X_6_2("Use the overload with a const JNINativeMethod[] instead.")
bool registerNativeMethods(const char *className, JNINativeMethod methods[], int size);
bool registerNativeMethods(jclass clazz, JNINativeMethod methods[], int size);
#endif
enum class OutputMode {
Silent,

View File

@ -122,7 +122,7 @@ static void callbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value)
void tst_QJniEnvironment::registerNativeMethods()
{
JNINativeMethod methods[] {
const JNINativeMethod methods[] {
{"callbackFromJava", "(Ljava/lang/String;)V", reinterpret_cast<void *>(callbackFromJava)}
};
@ -146,7 +146,7 @@ static void intCallbackFromJava(JNIEnv *env, jobject /*thiz*/, jint value)
void tst_QJniEnvironment::registerNativeMethodsByJclass()
{
JNINativeMethod methods[] {
const JNINativeMethod methods[] {
{ "intCallbackFromJava", "(I)V", reinterpret_cast<void *>(intCallbackFromJava) }
};