7#if defined(Q_QDOC) || defined(Q_OS_ANDROID)
9#include <QtCore/qjnitypes_impl.h>
10#include <QtCore/qjniobject.h>
15#define Q_DECLARE_JNI_TYPE_HELPER(Type) \
16namespace QtJniTypes { \
17struct Type : JObject<Type> \
19 using JObject::JObject; \
24#define Q_DECLARE_JNI_TYPE(Type, Signature) \
25Q_DECLARE_JNI_TYPE_HELPER(Type) \
27struct QtJniTypes::Traits<QtJniTypes::Type> { \
28 static constexpr auto signature() \
30 static_assert((Signature[0] == 'L' \
31 || Signature[0] == '[') \
32 && Signature[sizeof(Signature) - 2] == ';', \
33 "Type signature needs to start with 'L' or" \
34 " '[' and end with ';'"); \
35 return QtJniTypes::CTString(Signature); \
40#define Q_DECLARE_JNI_CLASS(Type, Signature) \
41Q_DECLARE_JNI_TYPE_HELPER(Type) \
43struct QtJniTypes::Traits<QtJniTypes::Type> { \
44 static constexpr auto className() \
46 return QtJniTypes::CTString(Signature); \
48 static constexpr auto signature() \
50 return QtJniTypes::CTString("L") \
52 + QtJniTypes::CTString(";"); \
58namespace QtJniMethods {
67template <
typename Arg>
struct PromotedType {
using Type = Arg; };
68template <>
struct PromotedType<bool> {
using Type = int; };
69template <>
struct PromotedType<char> {
using Type = int; };
70template <>
struct PromotedType<signed char> {
using Type = int; };
71template <>
struct PromotedType<unsigned char> {
using Type =
unsigned int; };
72template <>
struct PromotedType<short> {
using Type = int; };
73template <>
struct PromotedType<unsigned short> {
using Type =
unsigned int; };
74template <>
struct PromotedType<float> {
using Type = double; };
77template <
typename Arg>
78struct JNITypeForArgImpl
80 using Type = std::conditional_t<std::disjunction_v<std::is_base_of<QJniObject, Arg>,
81 std::is_base_of<QtJniTypes::JObjectBase, Arg>>,
82 jobject,
typename PromotedType<Arg>::Type>;
83 static Arg fromVarArg(
Type t)
85 return static_cast<Arg
>(
t);
90struct JNITypeForArgImpl<
QString>
101struct JNITypeForArgImpl<QJniArray<T>>
103 using Type = jobject;
105 static QJniArray<T> fromVarArg(
Type t)
107 return QJniArray<T>(
t);
112struct JNITypeForArgImpl<
QList<T>>
115 using ArrayType =
decltype(QJniArrayBase::fromContainer(std::declval<QList<T>>()));
116 using ArrayObjectType =
decltype(std::declval<ArrayType>().arrayObject());
117 using ElementType =
typename ArrayType::value_type;
119 using Type = ArrayObjectType;
121 static QList<T> fromVarArg(
Type t)
123 return QJniArray<ElementType>(
t).toContainer();
127template <
typename Arg>
128using JNITypeForArg =
typename JNITypeForArgImpl<std::decay_t<Arg>>
::Type;
129template <
typename Arg,
typename Type>
130static inline auto methodArgFromVarArg(
Type t)
132 return JNITypeForArgImpl<std::decay_t<Arg>>::fromVarArg(
t);
136template <
typename ...Args>
137static constexpr auto makeTupleFromArgsHelper(va_list
args)
139 return std::tuple(methodArgFromVarArg<Args>(va_arg(
args, JNITypeForArg<Args>))...);
142template <
typename Ret,
typename ...Args>
143static constexpr auto makeTupleFromArgs(Ret (*)(JNIEnv *, jobject, Args...), va_list
args)
145 return makeTupleFromArgsHelper<Args...>(
args);
147template <
typename Ret,
typename ...Args>
148static constexpr auto makeTupleFromArgs(Ret (*)(JNIEnv *, jclass, Args...), va_list
args)
150 return makeTupleFromArgsHelper<Args...>(
args);
154template <
typename Ret,
typename ...Args>
155auto nativeFunctionReturnType(Ret(*function)(Args...))
157 return function(std::declval<Args>()...);
168#define Q_DECLARE_JNI_NATIVE_METHOD_HELPER(Method) \
169static decltype(QtJniMethods::Detail::nativeFunctionReturnType(Method)) \
170va_##Method(JNIEnv *env, jclass thiz, ...) \
173 va_start(args, thiz); \
174 auto va_cleanup = qScopeGuard([&args]{ va_end(args); }); \
175 auto argTuple = QtJniMethods::Detail::makeTupleFromArgs(Method, args); \
176 return std::apply([env, thiz](auto &&... args) { \
177 return Method(env, thiz, args...); \
182#define Q_DECLARE_JNI_NATIVE_METHOD(...) \
183 QT_OVERLOADED_MACRO(QT_DECLARE_JNI_NATIVE_METHOD, __VA_ARGS__) \
185#define QT_DECLARE_JNI_NATIVE_METHOD_2(Method, Name) \
186namespace QtJniMethods { \
187Q_DECLARE_JNI_NATIVE_METHOD_HELPER(Method) \
188static constexpr auto Method##_signature = \
189 QtJniTypes::nativeMethodSignature(Method); \
190static const JNINativeMethod Method##_method = { \
191 #Name, Method##_signature.data(), \
192 reinterpret_cast<void *>(va_##Method) \
196#define QT_DECLARE_JNI_NATIVE_METHOD_1(Method) \
197 QT_DECLARE_JNI_NATIVE_METHOD_2(Method, Method) \
200#define Q_JNI_NATIVE_METHOD(Method) QtJniMethods::Method##_method
203#define Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(...) \
204 QT_OVERLOADED_MACRO(QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE, __VA_ARGS__) \
206#define QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE_2(Method, Name) \
207 Q_DECLARE_JNI_NATIVE_METHOD_HELPER(Method) \
208 static inline constexpr auto Method##_signature = QtJniTypes::nativeMethodSignature(Method); \
209 static inline const JNINativeMethod Method##_method = { \
210 #Name, Method##_signature.data(), reinterpret_cast<void *>(va_##Method) \
213#define QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE_1(Method) \
214 QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE_2(Method, Method) \
217#define Q_JNI_NATIVE_SCOPED_METHOD(Method, Scope) Scope::Method##_method
\macro QT_RESTRICTED_CAST_FROM_ASCII
Combined button and popup list for selecting options.
std::array< typename ArrayTypeHelper< ManualType, Types... >::type, sizeof...(Types)> ArrayType
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function