Add variadic template overloads for QJniObject/Environment methods
This allows the compiler to deduce the template arguments based on the provided method parameters, which we can then pass to the methodSignature and fieldSignature helpers to generate the signature string completely at compile time. Since we can't partially specialize template member functions, replace the specializations for void methods with compile-time-if branches in the general templates. This variadic template now prevents implicit conversion from the LiteralStorage types to const char* signatures, so catch the case where such a type ends up in the parameter list. Due to overload resolution rules for constructors, we need to explicitly disable the constructor if any of the arguments is a string literal type, as we have to keep the old C-style variadic function working for such calls. Add variations that use the variadic templates to the unit tests. Change-Id: I8734664b38bae932369462330a9a03302254c33c Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
parent
b9c55b5b9e
commit
601dbd6499
@ -231,6 +231,16 @@ jmethodID QJniEnvironment::findMethod(jclass clazz, const char *methodName, cons
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn template<typename ...Args> jmethodId QJniEnvironment::findMethod(jclass clazz, const char *methodName)
|
||||
\since 6.4
|
||||
|
||||
Searches for an instance method of a class \a clazz. The method is specified
|
||||
by its \a methodName, the signature is deduced from the template parameters.
|
||||
|
||||
Returns the method ID or \c nullptr if the method is not found.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Searches for a static method of a class \a clazz. The method is specified
|
||||
by its \a methodName and \a signature.
|
||||
@ -265,9 +275,28 @@ jmethodID QJniEnvironment::findStaticMethod(jclass clazz, const char *methodName
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn template<typename ...Args> jmethodId QJniEnvironment::findStaticMethod(jclass clazz, const char *methodName)
|
||||
\since 6.4
|
||||
|
||||
Searches for an instance method of a class \a clazz. The method is specified
|
||||
by its \a methodName, the signature is deduced from the template parameters.
|
||||
|
||||
Returns the method ID or \c nullptr if the method is not found.
|
||||
|
||||
\code
|
||||
QJniEnvironment env;
|
||||
jclass javaClass = env.findClass("org/qtproject/example/android/CustomClass");
|
||||
jmethodID methodId = env.findStaticMethod<void, jstring>(javaClass, "staticJavaMethod");
|
||||
QJniObject javaMessage = QJniObject::fromString("findStaticMethod example");
|
||||
QJniObject::callStaticMethod<void>(javaClass,
|
||||
methodId,
|
||||
javaMessage.object<jstring>());
|
||||
\endcode
|
||||
*/
|
||||
|
||||
/*!
|
||||
Searches for an member field of a class \a clazz. The field is specified
|
||||
Searches for a member field of a class \a clazz. The field is specified
|
||||
by its \a fieldName and \a signature.
|
||||
|
||||
Returns the field ID or \c nullptr if the field is not found.
|
||||
@ -288,6 +317,16 @@ jfieldID QJniEnvironment::findField(jclass clazz, const char *fieldName, const c
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn template<typename T> jfieldID QJniEnvironment::findField(jclass clazz, const char *fieldName)
|
||||
\since 6.4
|
||||
|
||||
Searches for a member field of a class \a clazz. The field is specified
|
||||
by its \a fieldName. The signature of the field is deduced from the template parameter.
|
||||
|
||||
Returns the field ID or \c nullptr if the field is not found.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Searches for a static field of a class \a clazz. The field is specified
|
||||
by its \a fieldName and \a signature.
|
||||
@ -310,6 +349,16 @@ jfieldID QJniEnvironment::findStaticField(jclass clazz, const char *fieldName, c
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn template<typename T> jfieldID QJniEnvironment::findStaticField(jclass clazz, const char *fieldName)
|
||||
\since 6.4
|
||||
|
||||
Searches for a static field of a class \a clazz. The field is specified
|
||||
by its \a fieldName. The signature of the field is deduced from the template parameter.
|
||||
|
||||
Returns the field ID or \c nullptr if the field is not found.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn JavaVM *QJniEnvironment::javaVM()
|
||||
|
||||
|
@ -44,6 +44,7 @@
|
||||
|
||||
#if defined(Q_QDOC) || defined(Q_OS_ANDROID)
|
||||
#include <jni.h>
|
||||
#include <QtCore/qjnitypes.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -60,9 +61,29 @@ public:
|
||||
JNIEnv *jniEnv() const;
|
||||
jclass findClass(const char *className);
|
||||
jmethodID findMethod(jclass clazz, const char *methodName, const char *signature);
|
||||
template<typename ...Args>
|
||||
jmethodID findMethod(jclass clazz, const char *methodName) {
|
||||
constexpr auto signature = QtJniTypes::methodSignature<Args...>();
|
||||
return findMethod(clazz, methodName, signature.data());
|
||||
}
|
||||
jmethodID findStaticMethod(jclass clazz, const char *methodName, const char *signature);
|
||||
template<typename ...Args>
|
||||
jmethodID findStaticMethod(jclass clazz, const char *methodName) {
|
||||
constexpr auto signature = QtJniTypes::methodSignature<Args...>();
|
||||
return findStaticMethod(clazz, methodName, signature.data());
|
||||
}
|
||||
jfieldID findField(jclass clazz, const char *fieldName, const char *signature);
|
||||
template<typename T>
|
||||
jfieldID findField(jclass clazz, const char *fieldName) {
|
||||
constexpr auto signature = QtJniTypes::fieldSignature<T>();
|
||||
return findField(clazz, fieldName, signature.data());
|
||||
}
|
||||
jfieldID findStaticField(jclass clazz, const char *fieldName, const char *signature);
|
||||
template<typename T>
|
||||
jfieldID findStaticField(jclass clazz, const char *fieldName) {
|
||||
constexpr auto signature = QtJniTypes::fieldSignature<T>();
|
||||
return findStaticField(clazz, fieldName, signature.data());
|
||||
}
|
||||
static JavaVM *javaVM();
|
||||
bool registerNativeMethods(const char *className, const JNINativeMethod methods[], int size);
|
||||
bool registerNativeMethods(jclass clazz, const JNINativeMethod methods[], int size);
|
||||
|
@ -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())
|
||||
{
|
||||
@ -671,6 +712,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.
|
||||
|
||||
@ -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.
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -57,8 +57,26 @@ public:
|
||||
QJniObject();
|
||||
explicit QJniObject(const char *className);
|
||||
explicit QJniObject(const char *className, const char *signature, ...);
|
||||
template<typename ...Args
|
||||
#ifndef Q_QDOC
|
||||
, std::enable_if_t<!std::disjunction_v<QtJniTypes::IsStringType<std::decay_t<Args>>...>>* = nullptr
|
||||
#endif
|
||||
>
|
||||
explicit QJniObject(const char *className, Args &&...args)
|
||||
: QJniObject(className, QtJniTypes::constructorSignature<Args...>().data(),
|
||||
std::forward<Args>(args)...)
|
||||
{}
|
||||
explicit QJniObject(jclass clazz);
|
||||
explicit QJniObject(jclass clazz, const char *signature, ...);
|
||||
template<typename ...Args
|
||||
#ifndef Q_QDOC
|
||||
, std::enable_if_t<!std::disjunction_v<QtJniTypes::IsStringType<std::decay_t<Args>>...>>* = nullptr
|
||||
#endif
|
||||
>
|
||||
explicit QJniObject(jclass clazz, Args &&...args)
|
||||
: QJniObject(clazz, QtJniTypes::constructorSignature<Args...>().data(),
|
||||
std::forward<Args>(args)...)
|
||||
{}
|
||||
QJniObject(jobject globalRef);
|
||||
~QJniObject();
|
||||
|
||||
@ -72,206 +90,135 @@ public:
|
||||
jclass objectClass() const;
|
||||
QByteArray className() const;
|
||||
|
||||
template <typename T>
|
||||
T callMethod(const char *methodName, const char *signature, ...) const
|
||||
{
|
||||
QtJniTypes::assertPrimitiveType<T>();
|
||||
QJniEnvironment env;
|
||||
T res{};
|
||||
jmethodID id = getCachedMethodID(env.jniEnv(), methodName, signature);
|
||||
if (id) {
|
||||
va_list args;
|
||||
va_start(args, signature);
|
||||
callMethodForType<T>(env.jniEnv(), res, object(), id, args);
|
||||
va_end(args);
|
||||
if (env.checkAndClearExceptions())
|
||||
res = {};
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <>
|
||||
void callMethod<void>(const char *methodName, const char *signature, ...) const
|
||||
template <typename Ret, typename ...Args>
|
||||
Ret callMethod(const char *methodName, const char *signature, Args &&...args) const
|
||||
{
|
||||
QtJniTypes::assertPrimitiveType<Ret>();
|
||||
QJniEnvironment env;
|
||||
jmethodID id = getCachedMethodID(env.jniEnv(), methodName, signature);
|
||||
if (id) {
|
||||
va_list args;
|
||||
va_start(args, signature);
|
||||
callVoidMethodV(env.jniEnv(), id, args);
|
||||
va_end(args);
|
||||
env.checkAndClearExceptions();
|
||||
if constexpr (std::is_same<Ret, void>::value) {
|
||||
callVoidMethodV(env.jniEnv(), id, std::forward<Args>(args)...);
|
||||
env.checkAndClearExceptions();
|
||||
} else {
|
||||
Ret res{};
|
||||
callMethodForType<Ret>(env.jniEnv(), res, object(), id, std::forward<Args>(args)...);
|
||||
if (env.checkAndClearExceptions())
|
||||
res = {};
|
||||
return res;
|
||||
}
|
||||
}
|
||||
if constexpr (!std::is_same<Ret, void>::value)
|
||||
return Ret{};
|
||||
}
|
||||
|
||||
template <typename Ret, typename ...Args>
|
||||
Ret callMethod(const char *methodName, Args &&...args) const
|
||||
{
|
||||
constexpr auto signature = QtJniTypes::methodSignature<Ret, Args...>();
|
||||
if constexpr (std::is_same<Ret, void>::value) {
|
||||
callMethod<void>(methodName, signature.data(), std::forward<Args>(args)...);
|
||||
} else {
|
||||
QtJniTypes::assertPrimitiveType<Ret>();
|
||||
return callMethod<Ret>(methodName, signature.data(), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T callMethod(const char *methodName) const
|
||||
template <typename Ret, typename ...Args>
|
||||
QJniObject callObjectMethod(const char *methodName, Args &&...args) const
|
||||
{
|
||||
QtJniTypes::assertPrimitiveType<T>();
|
||||
constexpr auto signature = QtJniTypes::methodSignature<T>();
|
||||
return callMethod<T>(methodName, signature);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QJniObject callObjectMethod(const char *methodName) const
|
||||
{
|
||||
QtJniTypes::assertObjectType<T>();
|
||||
constexpr auto signature = QtJniTypes::methodSignature<T>();
|
||||
return callObjectMethod(methodName, signature);
|
||||
QtJniTypes::assertObjectType<Ret>();
|
||||
constexpr auto signature = QtJniTypes::methodSignature<Ret, Args...>();
|
||||
return callObjectMethod(methodName, signature.data(), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
QJniObject callObjectMethod(const char *methodName, const char *signature, ...) const;
|
||||
|
||||
template <typename T>
|
||||
static T callStaticMethod(const char *className, const char *methodName,
|
||||
const char *signature, ...)
|
||||
{
|
||||
QtJniTypes::assertPrimitiveType<T>();
|
||||
QJniEnvironment env;
|
||||
T res{};
|
||||
jclass clazz = QJniObject::loadClass(className, env.jniEnv());
|
||||
if (clazz) {
|
||||
jmethodID id = getCachedMethodID(env.jniEnv(), clazz,
|
||||
QJniObject::toBinaryEncClassName(className),
|
||||
methodName, signature, true);
|
||||
if (id) {
|
||||
va_list args;
|
||||
va_start(args, signature);
|
||||
callStaticMethodForType<T>(env.jniEnv(), res, clazz, id, args);
|
||||
va_end(args);
|
||||
if (env.checkAndClearExceptions())
|
||||
res = {};
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <>
|
||||
void callStaticMethod<void>(const char *className, const char *methodName,
|
||||
const char *signature, ...)
|
||||
template <typename Ret, typename ...Args>
|
||||
static Ret callStaticMethod(const char *className, const char *methodName, const char *signature, Args &&...args)
|
||||
{
|
||||
QtJniTypes::assertPrimitiveType<Ret>();
|
||||
QJniEnvironment env;
|
||||
jclass clazz = QJniObject::loadClass(className, env.jniEnv());
|
||||
if (clazz) {
|
||||
jmethodID id = getCachedMethodID(env.jniEnv(), clazz,
|
||||
QJniObject::toBinaryEncClassName(className),
|
||||
methodName, signature, true);
|
||||
if (id) {
|
||||
va_list args;
|
||||
va_start(args, signature);
|
||||
env->CallStaticVoidMethodV(clazz, id, args);
|
||||
va_end(args);
|
||||
env.checkAndClearExceptions();
|
||||
}
|
||||
}
|
||||
return callStaticMethod<Ret>(clazz, methodName, signature, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T callStaticMethod(const char *className, const char *methodName)
|
||||
{
|
||||
QtJniTypes::assertPrimitiveType<T>();
|
||||
constexpr auto signature = QtJniTypes::methodSignature<T>();
|
||||
return callStaticMethod<T>(className, methodName, signature);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T callStaticMethod(jclass clazz, const char *methodName, const char *signature, ...)
|
||||
{
|
||||
QtJniTypes::assertPrimitiveType<T>();
|
||||
QJniEnvironment env;
|
||||
T res{};
|
||||
if (clazz) {
|
||||
jmethodID id = getMethodID(env.jniEnv(), clazz, methodName, signature, true);
|
||||
if (id) {
|
||||
va_list args;
|
||||
va_start(args, signature);
|
||||
callStaticMethodForType<T>(env.jniEnv(), res, clazz, id, args);
|
||||
va_end(args);
|
||||
if (env.checkAndClearExceptions())
|
||||
res = {};
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <>
|
||||
void callStaticMethod<void>(jclass clazz, const char *methodName,
|
||||
const char *signature, ...)
|
||||
template <typename Ret, typename ...Args>
|
||||
static Ret callStaticMethod(jclass clazz, const char *methodName, const char *signature, Args &&...args)
|
||||
{
|
||||
QtJniTypes::assertPrimitiveType<Ret>();
|
||||
QJniEnvironment env;
|
||||
if (clazz) {
|
||||
jmethodID id = getMethodID(env.jniEnv(), clazz, methodName, signature, true);
|
||||
if (id) {
|
||||
va_list args;
|
||||
va_start(args, signature);
|
||||
env->CallStaticVoidMethodV(clazz, id, args);
|
||||
va_end(args);
|
||||
return callStaticMethod<Ret, Args...>(clazz, id, std::forward<Args>(args)...);
|
||||
}
|
||||
if constexpr (!std::is_same<Ret, void>::value)
|
||||
return Ret{};
|
||||
}
|
||||
|
||||
template <typename Ret, typename ...Args>
|
||||
static Ret callStaticMethod(jclass clazz, jmethodID methodId, Args &&...args)
|
||||
{
|
||||
QtJniTypes::assertPrimitiveType<Ret>();
|
||||
QJniEnvironment env;
|
||||
if (clazz && methodId) {
|
||||
if constexpr (std::is_same<Ret, void>::value) {
|
||||
callStaticMethodForVoid(env.jniEnv(), clazz, methodId, std::forward<Args>(args)...);
|
||||
env.checkAndClearExceptions();
|
||||
} else {
|
||||
Ret res{};
|
||||
callStaticMethodForType<Ret>(env.jniEnv(), res, clazz, methodId, std::forward<Args>(args)...);
|
||||
if (env.checkAndClearExceptions())
|
||||
res = {};
|
||||
return res;
|
||||
}
|
||||
}
|
||||
if constexpr (!std::is_same<Ret, void>::value)
|
||||
return Ret{};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T callStaticMethod(jclass clazz, jmethodID methodId, ...)
|
||||
template <typename Ret, typename ...Args>
|
||||
static Ret callStaticMethod(const char *className, const char *methodName, Args &&...args)
|
||||
{
|
||||
QtJniTypes::assertPrimitiveType<T>();
|
||||
QtJniTypes::assertPrimitiveType<Ret>();
|
||||
QJniEnvironment env;
|
||||
T res{};
|
||||
if (clazz && methodId) {
|
||||
va_list args;
|
||||
va_start(args, methodId);
|
||||
callStaticMethodForType<T>(env.jniEnv(), res, clazz, methodId, args);
|
||||
va_end(args);
|
||||
if (env.checkAndClearExceptions())
|
||||
res = {};
|
||||
}
|
||||
return res;
|
||||
jclass clazz = QJniObject::loadClass(className, env.jniEnv());
|
||||
return callStaticMethod<Ret, Args...>(clazz, methodName, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <>
|
||||
void callStaticMethod<void>(jclass clazz, jmethodID methodId, ...)
|
||||
template <typename Ret, typename ...Args>
|
||||
static Ret callStaticMethod(jclass clazz, const char *methodName, Args &&...args)
|
||||
{
|
||||
QJniEnvironment env;
|
||||
if (clazz && methodId) {
|
||||
va_list args;
|
||||
va_start(args, methodId);
|
||||
env->CallStaticVoidMethodV(clazz, methodId, args);
|
||||
va_end(args);
|
||||
env.checkAndClearExceptions();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> static T callStaticMethod(jclass clazz, const char *methodName)
|
||||
{
|
||||
QtJniTypes::assertPrimitiveType<T>();
|
||||
constexpr auto signature = QtJniTypes::methodSignature<T>();
|
||||
return callStaticMethod<T>(clazz, methodName, signature);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static QJniObject callStaticObjectMethod(const char *className, const char *methodName)
|
||||
{
|
||||
QtJniTypes::assertObjectType<T>();
|
||||
constexpr auto signature = QtJniTypes::methodSignature<T>();
|
||||
return callStaticObjectMethod(className, methodName, signature);
|
||||
QtJniTypes::assertPrimitiveType<Ret>();
|
||||
constexpr auto signature = QtJniTypes::methodSignature<Ret, Args...>();
|
||||
return callStaticMethod<Ret>(clazz, methodName, signature.data(), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
static QJniObject callStaticObjectMethod(const char *className, const char *methodName,
|
||||
const char *signature, ...);
|
||||
|
||||
template <typename T>
|
||||
static QJniObject callStaticObjectMethod(jclass clazz, const char *methodName)
|
||||
{
|
||||
QtJniTypes::assertObjectType<T>();
|
||||
constexpr auto signature = QtJniTypes::methodSignature<T>();
|
||||
return callStaticObjectMethod(clazz, methodName, signature);
|
||||
}
|
||||
|
||||
static QJniObject callStaticObjectMethod(jclass clazz, const char *methodName,
|
||||
const char *signature, ...);
|
||||
|
||||
static QJniObject callStaticObjectMethod(jclass clazz, jmethodID methodId, ...);
|
||||
|
||||
|
||||
template <typename Ret, typename ...Args>
|
||||
static QJniObject callStaticObjectMethod(const char *className, const char *methodName, Args &&...args)
|
||||
{
|
||||
QtJniTypes::assertObjectType<Ret>();
|
||||
constexpr auto signature = QtJniTypes::methodSignature<Ret, Args...>();
|
||||
return callStaticObjectMethod(className, methodName, signature.data(), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Ret, typename ...Args>
|
||||
static QJniObject callStaticObjectMethod(jclass clazz, const char *methodName, Args &&...args)
|
||||
{
|
||||
QtJniTypes::assertObjectType<Ret>();
|
||||
constexpr auto signature = QtJniTypes::methodSignature<Ret, Args...>();
|
||||
return callStaticObjectMethod(clazz, methodName, signature.data(), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T> T getField(const char *fieldName) const
|
||||
{
|
||||
QtJniTypes::assertPrimitiveType<T>();
|
||||
@ -490,7 +437,7 @@ private:
|
||||
static jmethodID getMethodID(JNIEnv *env, jclass clazz, const char *name,
|
||||
const char *signature, bool isStatic = false);
|
||||
|
||||
void callVoidMethodV(JNIEnv *env, jmethodID id, va_list args) const;
|
||||
void callVoidMethodV(JNIEnv *env, jmethodID id, ...) const;
|
||||
QJniObject callObjectMethodV(const char *methodName, const char *signature,
|
||||
va_list args) const;
|
||||
|
||||
@ -510,8 +457,11 @@ private:
|
||||
|
||||
template<typename T>
|
||||
static constexpr void callMethodForType(JNIEnv *env, T &res, jobject obj,
|
||||
jmethodID id, va_list args)
|
||||
jmethodID id, ...)
|
||||
{
|
||||
va_list args = {};
|
||||
va_start(args, id);
|
||||
|
||||
if constexpr(std::is_same<T, jboolean>::value)
|
||||
res = env->CallBooleanMethodV(obj, id, args);
|
||||
else if constexpr(std::is_same<T, jbyte>::value)
|
||||
@ -530,12 +480,15 @@ private:
|
||||
res = env->CallDoubleMethodV(obj, id, args);
|
||||
else
|
||||
QtJniTypes::staticAssertTypeMismatch();
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr void callStaticMethodForType(JNIEnv *env, T &res, jclass clazz,
|
||||
jmethodID id, va_list args)
|
||||
jmethodID id, ...)
|
||||
{
|
||||
va_list args = {};
|
||||
va_start(args, id);
|
||||
if constexpr(std::is_same<T, jboolean>::value)
|
||||
res = env->CallStaticBooleanMethodV(clazz, id, args);
|
||||
else if constexpr(std::is_same<T, jbyte>::value)
|
||||
@ -554,8 +507,18 @@ private:
|
||||
res = env->CallStaticDoubleMethodV(clazz, id, args);
|
||||
else
|
||||
QtJniTypes::staticAssertTypeMismatch();
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void callStaticMethodForVoid(JNIEnv *env, jclass clazz, jmethodID id, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, id);
|
||||
env->CallStaticVoidMethodV(clazz, id, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
static constexpr void getFieldForType(JNIEnv *env, T &res, jobject obj,
|
||||
jfieldID id)
|
||||
|
@ -202,6 +202,10 @@ void tst_QJniEnvironment::findMethod()
|
||||
jmethodID methodId = env.findMethod(clazz, "toString", "()Ljava/lang/String;");
|
||||
QVERIFY(methodId != nullptr);
|
||||
|
||||
// existing method
|
||||
methodId = env.findMethod<jstring>(clazz, "toString");
|
||||
QVERIFY(methodId != nullptr);
|
||||
|
||||
// invalid signature
|
||||
jmethodID invalid = env.findMethod(clazz, "unknown", "()I");
|
||||
QVERIFY(invalid == nullptr);
|
||||
@ -219,6 +223,10 @@ void tst_QJniEnvironment::findStaticMethod()
|
||||
jmethodID staticMethodId = env.findStaticMethod(clazz, "parseInt", "(Ljava/lang/String;)I");
|
||||
QVERIFY(staticMethodId != nullptr);
|
||||
|
||||
// existing method
|
||||
staticMethodId = env.findStaticMethod<jint, jstring>(clazz, "parseInt");
|
||||
QVERIFY(staticMethodId != nullptr);
|
||||
|
||||
QJniObject parameter = QJniObject::fromString("123");
|
||||
jint result = QJniObject::callStaticMethod<jint>(clazz, staticMethodId,
|
||||
parameter.object<jstring>());
|
||||
@ -227,6 +235,8 @@ void tst_QJniEnvironment::findStaticMethod()
|
||||
// invalid method
|
||||
jmethodID invalid = env.findStaticMethod(clazz, "unknown", "()I");
|
||||
QVERIFY(invalid == nullptr);
|
||||
invalid = env.findStaticMethod<jint>(clazz, "unknown");
|
||||
QVERIFY(invalid == nullptr);
|
||||
// check that all exceptions are already cleared
|
||||
QVERIFY(!env.checkAndClearExceptions());
|
||||
}
|
||||
@ -240,6 +250,8 @@ void tst_QJniEnvironment::findField()
|
||||
// valid field
|
||||
jfieldID validId = env.findField(clazz, "INT_FIELD", "I");
|
||||
QVERIFY(validId != nullptr);
|
||||
validId = env.findField<jint>(clazz, "INT_FIELD");
|
||||
QVERIFY(validId != nullptr);
|
||||
|
||||
jmethodID constructorId = env.findMethod(clazz, "<init>", "()V");
|
||||
QVERIFY(constructorId != nullptr);
|
||||
@ -265,6 +277,8 @@ void tst_QJniEnvironment::findStaticField()
|
||||
// valid field
|
||||
jfieldID validId = env.findStaticField(clazz, "S_INT_FIELD", "I");
|
||||
QVERIFY(validId != nullptr);
|
||||
validId = env.findStaticField<jint>(clazz, "S_INT_FIELD");
|
||||
QVERIFY(validId != nullptr);
|
||||
|
||||
int size = env->GetStaticIntField(clazz, validId);
|
||||
QVERIFY(!env.checkAndClearExceptions());
|
||||
|
@ -166,6 +166,13 @@ void tst_QJniObject::ctor()
|
||||
QCOMPARE(string.toString(), object.toString());
|
||||
}
|
||||
|
||||
{
|
||||
QJniObject string = QJniObject::fromString(QLatin1String("Hello, Java"));
|
||||
QJniObject object("java/lang/String", string.object<jstring>());
|
||||
QVERIFY(object.isValid());
|
||||
QCOMPARE(string.toString(), object.toString());
|
||||
}
|
||||
|
||||
{
|
||||
QJniEnvironment env;
|
||||
jclass javaStringClass = env->FindClass("java/lang/String");
|
||||
@ -182,6 +189,16 @@ void tst_QJniObject::ctor()
|
||||
QVERIFY(stringCpy.isValid());
|
||||
QCOMPARE(qString, stringCpy.toString());
|
||||
}
|
||||
|
||||
{
|
||||
QJniEnvironment env;
|
||||
const QString qString = QLatin1String("Hello, Java");
|
||||
jclass javaStringClass = env->FindClass("java/lang/String");
|
||||
QJniObject string = QJniObject::fromString(qString);
|
||||
QJniObject stringCpy(javaStringClass, string.object<jstring>());
|
||||
QVERIFY(stringCpy.isValid());
|
||||
QCOMPARE(qString, stringCpy.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QJniObject::callMethodTest()
|
||||
@ -194,9 +211,12 @@ void tst_QJniObject::callMethodTest()
|
||||
const jboolean isEmpty = jString1.callMethod<jboolean>("isEmpty");
|
||||
QVERIFY(!isEmpty);
|
||||
|
||||
const jint ret = jString1.callMethod<jint>("compareToIgnoreCase",
|
||||
"(Ljava/lang/String;)I",
|
||||
jString2.object<jstring>());
|
||||
jint ret = jString1.callMethod<jint>("compareToIgnoreCase",
|
||||
"(Ljava/lang/String;)I",
|
||||
jString2.object<jstring>());
|
||||
QVERIFY(0 == ret);
|
||||
|
||||
ret = jString1.callMethod<jint>("compareToIgnoreCase", jString2.object<jstring>());
|
||||
QVERIFY(0 == ret);
|
||||
}
|
||||
|
||||
@ -219,6 +239,10 @@ void tst_QJniObject::callObjectMethodTest()
|
||||
"(II)Ljava/lang/String;",
|
||||
0, 4);
|
||||
QCOMPARE(subString.toString(), qString.mid(0, 4));
|
||||
|
||||
subString = jString.callObjectMethod<jstring>("substring", 0, 4);
|
||||
QCOMPARE(subString.toString(), qString.mid(0, 4));
|
||||
|
||||
}
|
||||
|
||||
void tst_QJniObject::stringConvertionTest()
|
||||
@ -276,6 +300,16 @@ void tst_QJniObject::callStaticObjectMethodClassName()
|
||||
QString returnedString = returnValue.toString();
|
||||
|
||||
QCOMPARE(returnedString, QString::fromLatin1("test format"));
|
||||
|
||||
returnValue = QJniObject::callStaticObjectMethod<jstring>("java/lang/String",
|
||||
"format",
|
||||
formatString.object<jstring>(),
|
||||
jobjectArray(0));
|
||||
QVERIFY(returnValue.isValid());
|
||||
|
||||
returnedString = returnValue.toString();
|
||||
|
||||
QCOMPARE(returnedString, QString::fromLatin1("test format"));
|
||||
}
|
||||
|
||||
void tst_QJniObject::callStaticObjectMethod()
|
||||
@ -297,6 +331,16 @@ void tst_QJniObject::callStaticObjectMethod()
|
||||
QString returnedString = returnValue.toString();
|
||||
|
||||
QCOMPARE(returnedString, QString::fromLatin1("test format"));
|
||||
|
||||
returnValue = QJniObject::callStaticObjectMethod<jstring>(cls,
|
||||
"format",
|
||||
formatString.object<jstring>(),
|
||||
jobjectArray(0));
|
||||
QVERIFY(returnValue.isValid());
|
||||
|
||||
returnedString = returnValue.toString();
|
||||
|
||||
QCOMPARE(returnedString, QString::fromLatin1("test format"));
|
||||
}
|
||||
|
||||
void tst_QJniObject::callStaticObjectMethodById()
|
||||
@ -336,6 +380,9 @@ void tst_QJniObject::callStaticBooleanMethod()
|
||||
"(Ljava/lang/String;)Z",
|
||||
parameter.object<jstring>());
|
||||
QVERIFY(b);
|
||||
|
||||
b = QJniObject::callStaticMethod<jboolean>(cls, "parseBoolean", parameter.object<jstring>());
|
||||
QVERIFY(b);
|
||||
}
|
||||
|
||||
{
|
||||
@ -347,6 +394,9 @@ void tst_QJniObject::callStaticBooleanMethod()
|
||||
"(Ljava/lang/String;)Z",
|
||||
parameter.object<jstring>());
|
||||
QVERIFY(!b);
|
||||
|
||||
b = QJniObject::callStaticMethod<jboolean>(cls, "parseBoolean", parameter.object<jstring>());
|
||||
QVERIFY(!b);
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,6 +437,10 @@ void tst_QJniObject::callStaticBooleanMethodClassName()
|
||||
"(Ljava/lang/String;)Z",
|
||||
parameter.object<jstring>());
|
||||
QVERIFY(b);
|
||||
b = QJniObject::callStaticMethod<jboolean>("java/lang/Boolean",
|
||||
"parseBoolean",
|
||||
parameter.object<jstring>());
|
||||
QVERIFY(b);
|
||||
}
|
||||
|
||||
{
|
||||
@ -398,6 +452,10 @@ void tst_QJniObject::callStaticBooleanMethodClassName()
|
||||
"(Ljava/lang/String;)Z",
|
||||
parameter.object<jstring>());
|
||||
QVERIFY(!b);
|
||||
b = QJniObject::callStaticMethod<jboolean>("java/lang/Boolean",
|
||||
"parseBoolean",
|
||||
parameter.object<jstring>());
|
||||
QVERIFY(!b);
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,7 +466,6 @@ void tst_QJniObject::callStaticByteMethodClassName()
|
||||
|
||||
jbyte returnValue = QJniObject::callStaticMethod<jbyte>("java/lang/Byte",
|
||||
"parseByte",
|
||||
"(Ljava/lang/String;)B",
|
||||
parameter.object<jstring>());
|
||||
QCOMPARE(returnValue, jbyte(number.toInt()));
|
||||
}
|
||||
@ -424,7 +481,6 @@ void tst_QJniObject::callStaticByteMethod()
|
||||
|
||||
jbyte returnValue = QJniObject::callStaticMethod<jbyte>(cls,
|
||||
"parseByte",
|
||||
"(Ljava/lang/String;)B",
|
||||
parameter.object<jstring>());
|
||||
QCOMPARE(returnValue, jbyte(number.toInt()));
|
||||
}
|
||||
@ -452,7 +508,6 @@ void tst_QJniObject::callStaticIntMethodClassName()
|
||||
|
||||
jint returnValue = QJniObject::callStaticMethod<jint>("java/lang/Integer",
|
||||
"parseInt",
|
||||
"(Ljava/lang/String;)I",
|
||||
parameter.object<jstring>());
|
||||
QCOMPARE(returnValue, number.toInt());
|
||||
}
|
||||
@ -469,7 +524,6 @@ void tst_QJniObject::callStaticIntMethod()
|
||||
|
||||
jint returnValue = QJniObject::callStaticMethod<jint>(cls,
|
||||
"parseInt",
|
||||
"(Ljava/lang/String;)I",
|
||||
parameter.object<jstring>());
|
||||
QCOMPARE(returnValue, number.toInt());
|
||||
}
|
||||
@ -494,7 +548,6 @@ void tst_QJniObject::callStaticCharMethodClassName()
|
||||
{
|
||||
jchar returnValue = QJniObject::callStaticMethod<jchar>("java/lang/Character",
|
||||
"toUpperCase",
|
||||
"(C)C",
|
||||
jchar('a'));
|
||||
QCOMPARE(returnValue, jchar('A'));
|
||||
}
|
||||
@ -508,7 +561,6 @@ void tst_QJniObject::callStaticCharMethod()
|
||||
|
||||
jchar returnValue = QJniObject::callStaticMethod<jchar>(cls,
|
||||
"toUpperCase",
|
||||
"(C)C",
|
||||
jchar('a'));
|
||||
QCOMPARE(returnValue, jchar('A'));
|
||||
}
|
||||
@ -533,7 +585,6 @@ void tst_QJniObject::callStaticDoubleMethodClassName ()
|
||||
|
||||
jdouble returnValue = QJniObject::callStaticMethod<jdouble>("java/lang/Double",
|
||||
"parseDouble",
|
||||
"(Ljava/lang/String;)D",
|
||||
parameter.object<jstring>());
|
||||
QCOMPARE(returnValue, number.toDouble());
|
||||
}
|
||||
@ -550,7 +601,6 @@ void tst_QJniObject::callStaticDoubleMethod()
|
||||
|
||||
jdouble returnValue = QJniObject::callStaticMethod<jdouble>(cls,
|
||||
"parseDouble",
|
||||
"(Ljava/lang/String;)D",
|
||||
parameter.object<jstring>());
|
||||
QCOMPARE(returnValue, number.toDouble());
|
||||
}
|
||||
@ -579,7 +629,6 @@ void tst_QJniObject::callStaticFloatMethodClassName()
|
||||
|
||||
jfloat returnValue = QJniObject::callStaticMethod<jfloat>("java/lang/Float",
|
||||
"parseFloat",
|
||||
"(Ljava/lang/String;)F",
|
||||
parameter.object<jstring>());
|
||||
QCOMPARE(returnValue, number.toFloat());
|
||||
}
|
||||
@ -596,7 +645,6 @@ void tst_QJniObject::callStaticFloatMethod()
|
||||
|
||||
jfloat returnValue = QJniObject::callStaticMethod<jfloat>(cls,
|
||||
"parseFloat",
|
||||
"(Ljava/lang/String;)F",
|
||||
parameter.object<jstring>());
|
||||
QCOMPARE(returnValue, number.toFloat());
|
||||
}
|
||||
@ -624,7 +672,6 @@ void tst_QJniObject::callStaticShortMethodClassName()
|
||||
|
||||
jshort returnValue = QJniObject::callStaticMethod<jshort>("java/lang/Short",
|
||||
"parseShort",
|
||||
"(Ljava/lang/String;)S",
|
||||
parameter.object<jstring>());
|
||||
QCOMPARE(returnValue, number.toShort());
|
||||
}
|
||||
@ -641,7 +688,6 @@ void tst_QJniObject::callStaticShortMethod()
|
||||
|
||||
jshort returnValue = QJniObject::callStaticMethod<jshort>(cls,
|
||||
"parseShort",
|
||||
"(Ljava/lang/String;)S",
|
||||
parameter.object<jstring>());
|
||||
QCOMPARE(returnValue, number.toShort());
|
||||
}
|
||||
@ -669,7 +715,6 @@ void tst_QJniObject::callStaticLongMethodClassName()
|
||||
|
||||
jlong returnValue = QJniObject::callStaticMethod<jlong>("java/lang/Long",
|
||||
"parseLong",
|
||||
"(Ljava/lang/String;)J",
|
||||
parameter.object<jstring>());
|
||||
QCOMPARE(returnValue, jlong(number.toLong()));
|
||||
}
|
||||
@ -685,7 +730,6 @@ void tst_QJniObject::callStaticLongMethod()
|
||||
|
||||
jlong returnValue = QJniObject::callStaticMethod<jlong>(cls,
|
||||
"parseLong",
|
||||
"(Ljava/lang/String;)J",
|
||||
parameter.object<jstring>());
|
||||
QCOMPARE(returnValue, jlong(number.toLong()));
|
||||
}
|
||||
@ -1044,9 +1088,15 @@ void tst_QJniObject::templateApiCheck()
|
||||
1,
|
||||
true,
|
||||
'c');
|
||||
QJniObject::callStaticMethod<void>(testClassName,
|
||||
"staticVoidMethodWithArgs",
|
||||
1,
|
||||
true,
|
||||
'c');
|
||||
|
||||
testClass.callMethod<void>("voidMethod");
|
||||
testClass.callMethod<void>("voidMethodWithArgs", "(IZC)V", 1, true, 'c');
|
||||
testClass.callMethod<void>("voidMethodWithArgs", 1, true, 'c');
|
||||
|
||||
// jboolean -----------------------------------------------------------------------------------
|
||||
QVERIFY(QJniObject::callStaticMethod<jboolean>(testClassName, "staticBooleanMethod"));
|
||||
@ -1056,6 +1106,11 @@ void tst_QJniObject::templateApiCheck()
|
||||
true,
|
||||
true,
|
||||
true));
|
||||
QVERIFY(QJniObject::callStaticMethod<jboolean>(testClassName,
|
||||
"staticBooleanMethodWithArgs",
|
||||
true,
|
||||
true,
|
||||
true));
|
||||
|
||||
QVERIFY(testClass.callMethod<jboolean>("booleanMethod"));
|
||||
QVERIFY(testClass.callMethod<jboolean>("booleanMethodWithArgs",
|
||||
@ -1063,6 +1118,10 @@ void tst_QJniObject::templateApiCheck()
|
||||
true,
|
||||
true,
|
||||
true));
|
||||
QVERIFY(testClass.callMethod<jboolean>("booleanMethodWithArgs",
|
||||
true,
|
||||
true,
|
||||
true));
|
||||
|
||||
// jbyte --------------------------------------------------------------------------------------
|
||||
QVERIFY(QJniObject::callStaticMethod<jbyte>(testClassName,
|
||||
@ -1073,9 +1132,15 @@ void tst_QJniObject::templateApiCheck()
|
||||
1,
|
||||
1,
|
||||
1) == A_BYTE_VALUE);
|
||||
QVERIFY(QJniObject::callStaticMethod<jbyte>(testClassName,
|
||||
"staticByteMethodWithArgs",
|
||||
jbyte(1),
|
||||
jbyte(1),
|
||||
jbyte(1)) == A_BYTE_VALUE);
|
||||
|
||||
QVERIFY(testClass.callMethod<jbyte>("byteMethod") == A_BYTE_VALUE);
|
||||
QVERIFY(testClass.callMethod<jbyte>("byteMethodWithArgs", "(BBB)B", 1, 1, 1) == A_BYTE_VALUE);
|
||||
QVERIFY(testClass.callMethod<jbyte>("byteMethodWithArgs", jbyte(1), jbyte(1), jbyte(1)) == A_BYTE_VALUE);
|
||||
|
||||
// jchar --------------------------------------------------------------------------------------
|
||||
QVERIFY(QJniObject::callStaticMethod<jchar>(testClassName,
|
||||
@ -1086,6 +1151,11 @@ void tst_QJniObject::templateApiCheck()
|
||||
jchar(1),
|
||||
jchar(1),
|
||||
jchar(1)) == A_CHAR_VALUE);
|
||||
QVERIFY(QJniObject::callStaticMethod<jchar>(testClassName,
|
||||
"staticCharMethodWithArgs",
|
||||
jchar(1),
|
||||
jchar(1),
|
||||
jchar(1)) == A_CHAR_VALUE);
|
||||
|
||||
QVERIFY(testClass.callMethod<jchar>("charMethod") == A_CHAR_VALUE);
|
||||
QVERIFY(testClass.callMethod<jchar>("charMethodWithArgs",
|
||||
@ -1093,6 +1163,10 @@ void tst_QJniObject::templateApiCheck()
|
||||
jchar(1),
|
||||
jchar(1),
|
||||
jchar(1)) == A_CHAR_VALUE);
|
||||
QVERIFY(testClass.callMethod<jchar>("charMethodWithArgs",
|
||||
jchar(1),
|
||||
jchar(1),
|
||||
jchar(1)) == A_CHAR_VALUE);
|
||||
|
||||
// jshort -------------------------------------------------------------------------------------
|
||||
QVERIFY(QJniObject::callStaticMethod<jshort>(testClassName,
|
||||
@ -1103,6 +1177,11 @@ void tst_QJniObject::templateApiCheck()
|
||||
jshort(1),
|
||||
jshort(1),
|
||||
jshort(1)) == A_SHORT_VALUE);
|
||||
QVERIFY(QJniObject::callStaticMethod<jshort>(testClassName,
|
||||
"staticShortMethodWithArgs",
|
||||
jshort(1),
|
||||
jshort(1),
|
||||
jshort(1)) == A_SHORT_VALUE);
|
||||
|
||||
QVERIFY(testClass.callMethod<jshort>("shortMethod") == A_SHORT_VALUE);
|
||||
QVERIFY(testClass.callMethod<jshort>("shortMethodWithArgs",
|
||||
@ -1110,6 +1189,10 @@ void tst_QJniObject::templateApiCheck()
|
||||
jshort(1),
|
||||
jshort(1),
|
||||
jshort(1)) == A_SHORT_VALUE);
|
||||
QVERIFY(testClass.callMethod<jshort>("shortMethodWithArgs",
|
||||
jshort(1),
|
||||
jshort(1),
|
||||
jshort(1)) == A_SHORT_VALUE);
|
||||
|
||||
// jint ---------------------------------------------------------------------------------------
|
||||
QVERIFY(QJniObject::callStaticMethod<jint>(testClassName,
|
||||
@ -1120,6 +1203,11 @@ void tst_QJniObject::templateApiCheck()
|
||||
jint(1),
|
||||
jint(1),
|
||||
jint(1)) == A_INT_VALUE);
|
||||
QVERIFY(QJniObject::callStaticMethod<jint>(testClassName,
|
||||
"staticIntMethodWithArgs",
|
||||
jint(1),
|
||||
jint(1),
|
||||
jint(1)) == A_INT_VALUE);
|
||||
|
||||
QVERIFY(testClass.callMethod<jint>("intMethod") == A_INT_VALUE);
|
||||
QVERIFY(testClass.callMethod<jint>("intMethodWithArgs",
|
||||
@ -1127,6 +1215,10 @@ void tst_QJniObject::templateApiCheck()
|
||||
jint(1),
|
||||
jint(1),
|
||||
jint(1)) == A_INT_VALUE);
|
||||
QVERIFY(testClass.callMethod<jint>("intMethodWithArgs",
|
||||
jint(1),
|
||||
jint(1),
|
||||
jint(1)) == A_INT_VALUE);
|
||||
|
||||
// jlong --------------------------------------------------------------------------------------
|
||||
QVERIFY(QJniObject::callStaticMethod<jlong>(testClassName,
|
||||
@ -1137,6 +1229,11 @@ void tst_QJniObject::templateApiCheck()
|
||||
jlong(1),
|
||||
jlong(1),
|
||||
jlong(1)) == A_LONG_VALUE);
|
||||
QVERIFY(QJniObject::callStaticMethod<jlong>(testClassName,
|
||||
"staticLongMethodWithArgs",
|
||||
jlong(1),
|
||||
jlong(1),
|
||||
jlong(1)) == A_LONG_VALUE);
|
||||
|
||||
QVERIFY(testClass.callMethod<jlong>("longMethod") == A_LONG_VALUE);
|
||||
QVERIFY(testClass.callMethod<jlong>("longMethodWithArgs",
|
||||
@ -1144,6 +1241,10 @@ void tst_QJniObject::templateApiCheck()
|
||||
jlong(1),
|
||||
jlong(1),
|
||||
jlong(1)) == A_LONG_VALUE);
|
||||
QVERIFY(testClass.callMethod<jlong>("longMethodWithArgs",
|
||||
jlong(1),
|
||||
jlong(1),
|
||||
jlong(1)) == A_LONG_VALUE);
|
||||
|
||||
// jfloat -------------------------------------------------------------------------------------
|
||||
QVERIFY(QJniObject::callStaticMethod<jfloat>(testClassName,
|
||||
@ -1154,6 +1255,11 @@ void tst_QJniObject::templateApiCheck()
|
||||
jfloat(1.1),
|
||||
jfloat(1.1),
|
||||
jfloat(1.1)) == A_FLOAT_VALUE);
|
||||
QVERIFY(QJniObject::callStaticMethod<jfloat>(testClassName,
|
||||
"staticFloatMethodWithArgs",
|
||||
jfloat(1.1),
|
||||
jfloat(1.1),
|
||||
jfloat(1.1)) == A_FLOAT_VALUE);
|
||||
|
||||
QVERIFY(testClass.callMethod<jfloat>("floatMethod") == A_FLOAT_VALUE);
|
||||
QVERIFY(testClass.callMethod<jfloat>("floatMethodWithArgs",
|
||||
@ -1161,6 +1267,10 @@ void tst_QJniObject::templateApiCheck()
|
||||
jfloat(1.1),
|
||||
jfloat(1.1),
|
||||
jfloat(1.1)) == A_FLOAT_VALUE);
|
||||
QVERIFY(testClass.callMethod<jfloat>("floatMethodWithArgs",
|
||||
jfloat(1.1),
|
||||
jfloat(1.1),
|
||||
jfloat(1.1)) == A_FLOAT_VALUE);
|
||||
|
||||
// jdouble ------------------------------------------------------------------------------------
|
||||
QVERIFY(QJniObject::callStaticMethod<jdouble>(testClassName,
|
||||
@ -1171,6 +1281,11 @@ void tst_QJniObject::templateApiCheck()
|
||||
jdouble(1.1),
|
||||
jdouble(1.1),
|
||||
jdouble(1.1)) == A_DOUBLE_VALUE);
|
||||
QVERIFY(QJniObject::callStaticMethod<jdouble>(testClassName,
|
||||
"staticDoubleMethodWithArgs",
|
||||
jdouble(1.1),
|
||||
jdouble(1.1),
|
||||
jdouble(1.1)) == A_DOUBLE_VALUE);
|
||||
|
||||
QVERIFY(testClass.callMethod<jdouble>("doubleMethod") == A_DOUBLE_VALUE);
|
||||
QVERIFY(testClass.callMethod<jdouble>("doubleMethodWithArgs",
|
||||
@ -1178,6 +1293,10 @@ void tst_QJniObject::templateApiCheck()
|
||||
jdouble(1.1),
|
||||
jdouble(1.1),
|
||||
jdouble(1.1)) == A_DOUBLE_VALUE);
|
||||
QVERIFY(testClass.callMethod<jdouble>("doubleMethodWithArgs",
|
||||
jdouble(1.1),
|
||||
jdouble(1.1),
|
||||
jdouble(1.1)) == A_DOUBLE_VALUE);
|
||||
|
||||
// jobject ------------------------------------------------------------------------------------
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user