summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qjniobject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qjniobject.cpp')
-rw-r--r--src/corelib/kernel/qjniobject.cpp151
1 files changed, 114 insertions, 37 deletions
diff --git a/src/corelib/kernel/qjniobject.cpp b/src/corelib/kernel/qjniobject.cpp
index fcc4851c74c..e801aa958f3 100644
--- a/src/corelib/kernel/qjniobject.cpp
+++ b/src/corelib/kernel/qjniobject.cpp
@@ -76,55 +76,77 @@ using namespace Qt::StringLiterals;
\section1 Method Signatures
- For functions that take no arguments, QJniObject provides convenience functions that will use
- the correct signature based on the provided template type. For example:
+ QJniObject provides convenience functions that will use the correct signature based on the
+ provided template types. For functions that only return and take \l {JNI types}, the
+ signature can be generate at compile time:
\code
jint x = QJniObject::callMethod<jint>("getSize");
QJniObject::callMethod<void>("touch");
+ jint ret = jString1.callMethod<jint>("compareToIgnoreCase", jString2.object<jstring>());
\endcode
- In other cases you will need to supply the signature yourself, and it is important that the
- signature matches the function you want to call. The signature structure is
- \c "(ArgumentsTypes)ReturnType". Array types in the signature must have the \c {[} prefix,
- and the fully-qualified \c Object type names must have the \c L prefix and the \c ; suffix.
+ These functions are variadic templates, and the compiler will deduce the template arguments
+ from the actual argument types. In many situations, only the return type needs to be provided
+ explicitly.
- The example below demonstrates how to call two different static functions:
+ For functions that take other argument types, you need to supply the signature yourself. It is
+ important that the signature matches the function you want to call. The example below
+ demonstrates how to call different static functions:
\code
// Java class
package org.qtproject.qt;
class TestClass
{
- static String fromNumber(int x) { ... }
- static String[] stringArray(String s1, String s2) { ... }
+ static TestClass create() { ... }
+ static String fromNumber(int x) { ... }
+ static String[] stringArray(String s1, String s2) { ... }
}
\endcode
- The signature for the first function is \c {"(I)Ljava/lang/String;"}:
+ The signature structure is \c "(ArgumentsTypes)ReturnType". Array types in the signature
+ must have the \c {[} prefix, and the fully-qualified \c Object type names must have the
+ \c L prefix and the \c ; suffix. The signature for the \c create function is
+ \c {"()Lorg/qtproject/qt/TestClass;}. The signatures for the second and third functions
+ are \c {"(I)Ljava/lang/String;"} and
+ \c {"(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;"}, respectively.
+
+ We can call the \c create() function like this:
+
+ \code
+ // C++ code
+ QJniObject testClass = QJniObject::callStaticObjectMethod("org/qtproject/qt/TestClass",
+ "create",
+ "()Lorg/qtproject/qt/TestClass;");
+ \endcode
+
+ For the second and third function we can rely on QJniObject's template methods to create
+ the implicit signature string, but we can also pass the signature string explicitly:
\code
// C++ code
QJniObject stringNumber = QJniObject::callStaticObjectMethod("org/qtproject/qt/TestClass",
- "fromNumber"
- "(I)Ljava/lang/String;",
- 10);
+ "fromNumber",
+ "(I)Ljava/lang/String;", 10);
\endcode
- and the signature for the second function is
- \c {"(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;"}:
+ For the implicit signature creation to work we need to specify the return type explicitly:
\code
// C++ code
QJniObject string1 = QJniObject::fromString("String1");
QJniObject string2 = QJniObject::fromString("String2");
- QJniObject stringArray = QJniObject::callStaticObjectMethod("org/qtproject/qt/TestClass",
+ QJniObject stringArray = QJniObject::callStaticObjectMethod<jstringArray>(
+ "org/qtproject/qt/TestClass",
"stringArray"
- "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;"
string1.object<jstring>(),
string2.object<jstring>());
\endcode
+ Note that while he first template parameter specifies the return type of the Java
+ function, the method will still return a QJniObject.
+
\section1 Handling Java Exception
After calling Java functions that might throw exceptions, it is important
@@ -403,9 +425,12 @@ jmethodID QJniObject::getMethodID(JNIEnv *env,
return id;
}
-void QJniObject::callVoidMethodV(JNIEnv *env, jmethodID id, va_list args) const
+void QJniObject::callVoidMethodV(JNIEnv *env, jmethodID id, ...) const
{
+ va_list args;
+ va_start(args, id);
env->CallVoidMethodV(d->m_jobject, id, args);
+ va_end(args);
}
jmethodID QJniObject::getCachedMethodID(JNIEnv *env,
@@ -620,6 +645,22 @@ QJniObject::QJniObject(const char *className, const char *signature, ...)
}
}
+/*!
+ \fn template<typename ...Args> QJniObject::QJniObject(const char *className, Args &&...args)
+ \since 6.4
+
+ Constructs a new JNI object by calling the constructor of \a className with
+ the arguments \a args. This constructor is only available if all \a args are
+ known \l {JNI Types}.
+
+ \code
+ QJniEnvironment env;
+ char* str = "Hello";
+ jstring myJStringArg = env->NewStringUTF(str);
+ QJniObject myNewJavaString("java/lang/String", myJStringArg);
+ \endcode
+*/
+
QJniObject::QJniObject(const char *className, const char *signature, const QVaListPrivate &args)
: d(new QJniObjectPrivate())
{
@@ -672,6 +713,21 @@ QJniObject::QJniObject(jclass clazz, const char *signature, ...)
}
/*!
+ \fn template<typename ...Args> QJniObject::QJniObject(jclass clazz, Args &&...args)
+ \since 6.4
+
+ Constructs a new JNI object from \a clazz by calling the constructor with
+ the arguments \a args. This constructor is only available if all \a args are
+ known \l {JNI Types}.
+
+ \code
+ QJniEnvironment env;
+ jclass myClazz = env.findClass("org/qtproject/qt/TestClass");
+ QJniObject(myClazz, 3);
+ \endcode
+*/
+
+/*!
Constructs a new JNI object by calling the default constructor of \a clazz.
\note The QJniObject will create a new reference to the class \a clazz
@@ -883,10 +939,11 @@ QJniObject QJniObject::callStaticObjectMethodV(jclass clazz,
}
/*!
- \fn template <typename T> T QJniObject::callMethod(const char *methodName, const char *signature, ...) const
+ \fn template <typename Ret, typename ...Args> Ret QJniObject::callMethod(const char *methodName, const char *signature, Args &&...args) const
+ \since 6.4
Calls the object's method \a methodName with \a signature specifying the types of any
- subsequent arguments.
+ subsequent arguments \a args.
\code
QJniObject myJavaStrin("org/qtproject/qt/TestClass");
@@ -896,21 +953,25 @@ QJniObject QJniObject::callStaticObjectMethodV(jclass clazz,
*/
/*!
- \fn template <typename T> T QJniObject::callMethod(const char *methodName) const
+ \fn template <typename Ret, typename ...Args> Ret QJniObject::callMethod(const char *methodName, Args &&...args) const
+ \since 6.4
- Calls the method \a methodName and returns the value.
+ Calls the method \a methodName with arguments \a args and returns the value.
\code
QJniObject myJavaStrin("org/qtproject/qt/TestClass");
jint size = myJavaString.callMethod<jint>("length");
\endcode
+
+ The method signature is deduced at compile time from \c Ret and the types of \a args.
*/
/*!
- \fn template <typename T> T QJniObject::callStaticMethod(const char *className, const char *methodName, const char *signature, ...)
+ \fn template <typename Ret, typename ...Args> Ret QJniObject::callStaticMethod(const char *className, const char *methodName, const char *signature, Args &&...args)
+ \since 6.4
Calls the static method \a methodName from class \a className with \a signature
- specifying the types of any subsequent arguments.
+ specifying the types of any subsequent arguments \a args.
\code
jint a = 2;
@@ -920,17 +981,21 @@ QJniObject QJniObject::callStaticObjectMethodV(jclass clazz,
*/
/*!
- \fn template <typename T> T QJniObject::callStaticMethod(const char *className, const char *methodName)
+ \fn template <typename Ret, typename ...Args> Ret QJniObject::callStaticMethod(const char *className, const char *methodName, Args &&...args)
+ \since 6.4
- Calls the static method \a methodName on class \a className and returns the value.
+ Calls the static method \a methodName on class \a className with arguments \a args,
+ and returns the value of type \c Ret.
\code
jint value = QJniObject::callStaticMethod<jint>("MyClass", "staticMethod");
\endcode
+
+ The method signature is deduced at compile time from \c Ret and the types of \a args.
*/
/*!
- \fn template <typename T> T QJniObject::callStaticMethod(jclass clazz, const char *methodName, const char *signature, ...)
+ \fn template <typename Ret, typename ...Args> Ret QJniObject::callStaticMethod(jclass clazz, const char *methodName, const char *signature, Args &&...args)
Calls the static method \a methodName from \a clazz with \a signature
specifying the types of any subsequent arguments.
@@ -945,7 +1010,8 @@ QJniObject QJniObject::callStaticObjectMethodV(jclass clazz,
*/
/*!
- \fn template <typename T> T QJniObject::callStaticMethod(jclass clazz, jmethodID methodId, ...)
+ \fn template <typename Ret, typename ...Args> Ret QJniObject::callStaticMethod(jclass clazz, jmethodID methodId, Args &&...args)
+ \since 6.4
Calls the static method identified by \a methodId from the class \a clazz
with any subsequent arguments. Useful when \a clazz and \a methodId are
@@ -964,7 +1030,8 @@ QJniObject QJniObject::callStaticObjectMethodV(jclass clazz,
*/
/*!
- \fn template <typename T> T QJniObject::callStaticMethod(jclass clazz, const char *methodName)
+ \fn template <typename Ret, typename ...Args> Ret QJniObject::callStaticMethod(jclass clazz, const char *methodName, Args &&...args)
+ \since 6.4
Calls the static method \a methodName on \a clazz and returns the value.
@@ -973,6 +1040,8 @@ QJniObject QJniObject::callStaticObjectMethodV(jclass clazz,
jclass javaMathClass = env.findClass("java/lang/Math");
jdouble randNr = QJniObject::callStaticMethod<jdouble>(javaMathClass, "random");
\endcode
+
+ The method signature is deduced at compile time from \c Ret and the types of \a args.
*/
/*!
@@ -1090,32 +1159,40 @@ QJniObject QJniObject::callStaticObjectMethod(jclass clazz, jmethodID methodId,
}
/*!
- \fn QJniObject QJniObject::callObjectMethod(const char *methodName) const
+ \fn template<typename Ret, typename ...Args> QJniObject QJniObject::callObjectMethod(const char *methodName, Args &&...args) const
+ \since 6.4
- Calls the Java objects method \a methodName and returns a new QJniObject for
- the returned Java object.
+ Calls the Java objects method \a methodName with arguments \a args and returns a
+ new QJniObject for the returned Java object.
\code
QJniObject myJavaString = QJniObject::fromString("Hello, Java");
QJniObject myJavaString2 = myJavaString1.callObjectMethod<jstring>("toString");
\endcode
+
+ The method signature is deduced at compile time from \c Ret and the types of \a args.
*/
/*!
- \fn QJniObject QJniObject::callStaticObjectMethod(const char *className, const char *methodName)
+ \fn template<typename Ret, typename ...Args> QJniObject QJniObject::callStaticObjectMethod(const char *className, const char *methodName, Args &&...args)
+ \since 6.4
- Calls the static method with \a methodName on the class \a className.
+ Calls the static method with \a methodName on the class \a className, passing
+ arguments \a args, and returns a new QJniObject for the returned Java object.
\code
QJniObject string = QJniObject::callStaticObjectMethod<jstring>("CustomClass", "getClassName");
\endcode
+
+ The method signature is deduced at compile time from \c Ret and the types of \a args.
*/
/*!
- \fn QJniObject QJniObject::callStaticObjectMethod(jclass clazz, const char *methodName)
-
- Calls the static method with \a methodName on \a clazz.
+ \fn template<typename Ret, typename ...Args> QJniObject QJniObject::callStaticObjectMethod(jclass clazz, const char *methodName, Args &&...args)
+ \since 6.4
+ Calls the static method with \a methodName on \a clazz, passing arguments \a args,
+ and returns a new QJniObject for the returned Java object.
*/
/*!