Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
PIM
Itinerary
Commits
82c4fe51
Commit
82c4fe51
authored
Dec 06, 2021
by
Volker Krause
Browse files
Implement JNI basic type array decoding
parent
1090ec41
Pipeline
#106178
passed with stage
in 1 minute and 16 seconds
Changes
5
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
autotests/jniarraytest.cpp
View file @
82c4fe51
...
...
@@ -34,6 +34,10 @@ private Q_SLOTS:
const
auto
a2
=
Jni
::
fromArray
<
QStringList
>
(
array
);
QCOMPARE
(
a2
.
size
(),
2
);
QCOMPARE
(
a2
,
QStringList
({
QStringLiteral
(
"ctor: 0"
),
QStringLiteral
(
"ctor: 1"
)
}));
JNIEnv
::
m_arrayLength
=
4
;
const
auto
a3
=
Jni
::
fromArray
<
std
::
vector
<
int
>>
(
array
);
QCOMPARE
(
a3
.
size
(),
4
);
#endif
}
};
...
...
autotests/jnimethodtest.cpp
View file @
82c4fe51
...
...
@@ -25,6 +25,7 @@ public:
JNI_METHOD
(
void
,
startIntent
,
android
::
content
::
Intent
)
JNI_METHOD
(
android
::
content
::
Intent
,
getIntent
)
JNI_METHOD
(
Jni
::
Array
<
java
::
lang
::
String
>
,
getStringList
)
JNI_METHOD
(
Jni
::
Array
<
jshort
>
,
getShortList
)
JNI_PROPERTY
(
java
::
lang
::
String
,
name
)
...
...
@@ -101,11 +102,12 @@ private Q_SLOTS:
j
=
obj
.
getStringList
();
QStringList
l
=
obj
.
getStringList
();
std
::
vector
<
QString
>
l2
=
obj
.
getStringList
();
std
::
vector
<
jshort
>
l3
=
obj
.
getShortList
();
// nullptr arguments
obj
.
startIntent
(
nullptr
);
QCOMPARE
(
obj
.
handle
().
protocol
().
size
(),
2
1
);
QCOMPARE
(
obj
.
handle
().
protocol
().
size
(),
2
2
);
QCOMPARE
(
obj
.
handle
().
protocol
()[
0
],
QLatin1String
(
"callObjectMethod: getName ()Ljava/lang/String; ()"
));
QCOMPARE
(
obj
.
handle
().
protocol
()[
1
],
QLatin1String
(
"callMethod: setName (Ljava/lang/String;)V (o)"
));
QCOMPARE
(
obj
.
handle
().
protocol
()[
2
],
QLatin1String
(
"callMethod: setName (Ljava/lang/String;)V (o)"
));
...
...
@@ -127,7 +129,8 @@ private Q_SLOTS:
QCOMPARE
(
obj
.
handle
().
protocol
()[
17
],
QLatin1String
(
"callObjectMethod: getStringList ()[Ljava/lang/String; ()"
));
QCOMPARE
(
obj
.
handle
().
protocol
()[
18
],
QLatin1String
(
"callObjectMethod: getStringList ()[Ljava/lang/String; ()"
));
QCOMPARE
(
obj
.
handle
().
protocol
()[
19
],
QLatin1String
(
"callObjectMethod: getStringList ()[Ljava/lang/String; ()"
));
QCOMPARE
(
obj
.
handle
().
protocol
()[
20
],
QLatin1String
(
"callMethod: startIntent (Landroid/content/Intent;)V (o)"
));
QCOMPARE
(
obj
.
handle
().
protocol
()[
20
],
QLatin1String
(
"callObjectMethod: getShortList ()[S ()"
));
QCOMPARE
(
obj
.
handle
().
protocol
()[
21
],
QLatin1String
(
"callMethod: startIntent (Landroid/content/Intent;)V (o)"
));
#if 0
// stuff that must not compile
obj.setName(42);
...
...
src/kandroidextras/fake/QAndroidJniEnvironment
View file @
82c4fe51
...
...
@@ -12,10 +12,11 @@
class QAndroidJniEnvironment
{
public:
inline operator JNIEnv*() const { return &m_env; }
inline JNIEnv* operator->() { return &m_env; }
private:
JNIEnv m_env;
mutable
JNIEnv m_env;
};
#endif
src/kandroidextras/fake/jni.h
View file @
82c4fe51
...
...
@@ -22,11 +22,21 @@ typedef int64_t jlong;
typedef
float
jfloat
;
typedef
double
jdouble
;
typedef
jint
jsize
;
typedef
void
*
jobject
;
typedef
jobject
jclass
;
typedef
jobject
jstring
;
typedef
jobject
jarray
;
typedef
jarray
jobjectArray
;
typedef
jarray
jbooleanArray
;
typedef
jarray
jbyteArray
;
typedef
jarray
jcharArray
;
typedef
jarray
jshortArray
;
typedef
jarray
jintArray
;
typedef
jarray
jlongArray
;
typedef
jarray
jfloatArray
;
typedef
jarray
jdoubleArray
;
struct
JNIEnv
{
...
...
@@ -35,7 +45,46 @@ struct JNIEnv
inline
int
GetArrayLength
(
jobjectArray
)
{
return
m_arrayLength
;
}
inline
jobject
GetObjectArrayElement
(
jobjectArray
,
int
index
)
{
return
reinterpret_cast
<
jobject
>
(
index
);
}
inline
jbooleanArray
NewBooleanArray
(
jsize
)
{
return
nullptr
;
}
inline
jbyteArray
NewByteArray
(
jsize
)
{
return
nullptr
;
}
inline
jcharArray
NewCharArray
(
jsize
)
{
return
nullptr
;
}
inline
jshortArray
NewShortArray
(
jsize
)
{
return
nullptr
;
}
inline
jintArray
NewIntArray
(
jsize
)
{
return
nullptr
;
}
inline
jlongArray
NewLongArray
(
jsize
)
{
return
nullptr
;
}
inline
jfloatArray
NewFloatArray
(
jsize
)
{
return
nullptr
;
}
inline
jdoubleArray
NewDoubleArray
(
jsize
)
{
return
nullptr
;
}
inline
jboolean
*
GetBooleanArrayElements
(
jbooleanArray
,
jboolean
*
)
{
return
new
jboolean
[
m_arrayLength
];
}
inline
jbyte
*
GetByteArrayElements
(
jbyteArray
,
jboolean
*
)
{
return
new
jbyte
[
m_arrayLength
];
}
inline
jchar
*
GetCharArrayElements
(
jcharArray
,
jboolean
*
)
{
return
new
jchar
[
m_arrayLength
];
}
inline
jshort
*
GetShortArrayElements
(
jshortArray
,
jboolean
*
)
{
return
new
jshort
[
m_arrayLength
];
}
inline
jint
*
GetIntArrayElements
(
jintArray
,
jboolean
*
)
{
return
new
jint
[
m_arrayLength
];
}
inline
jlong
*
GetLongArrayElements
(
jlongArray
,
jboolean
*
)
{
return
new
jlong
[
m_arrayLength
];
}
inline
jfloat
*
GetFloatArrayElements
(
jfloatArray
,
jboolean
*
)
{
return
new
jfloat
[
m_arrayLength
];
}
inline
jdouble
*
GetDoubleArrayElements
(
jdoubleArray
,
jboolean
*
)
{
return
new
jdouble
[
m_arrayLength
];
}
inline
void
ReleaseBooleanArrayElements
(
jbooleanArray
,
jboolean
*
data
,
jint
)
{
delete
[]
data
;
}
inline
void
ReleaseByteArrayElements
(
jbyteArray
,
jbyte
*
data
,
jint
)
{
delete
[]
data
;
}
inline
void
ReleaseCharArrayElements
(
jcharArray
,
jchar
*
data
,
jint
)
{
delete
[]
data
;
}
inline
void
ReleaseShortArrayElements
(
jshortArray
,
jshort
*
data
,
jint
)
{
delete
[]
data
;
}
inline
void
ReleaseIntArrayElements
(
jintArray
,
jint
*
data
,
jint
)
{
delete
[]
data
;
}
inline
void
ReleaseLongArrayElements
(
jlongArray
,
jlong
*
data
,
jint
)
{
delete
[]
data
;
}
inline
void
ReleaseFloatArrayElements
(
jfloatArray
,
jfloat
*
data
,
jint
)
{
delete
[]
data
;
}
inline
void
ReleaseDoubleArrayElements
(
jdoubleArray
,
jdouble
*
data
,
jint
)
{
delete
[]
data
;
}
inline
void
SetBooleanArrayRegion
(
jbooleanArray
,
jsize
,
jsize
,
const
jboolean
*
)
{}
inline
void
SetByteArrayRegion
(
jbyteArray
,
jsize
,
jsize
,
const
jbyte
*
)
{}
inline
void
SetCharArrayRegion
(
jcharArray
,
jsize
,
jsize
,
const
jchar
*
)
{}
inline
void
SetShortArrayRegion
(
jshortArray
,
jsize
,
jsize
,
const
jshort
*
)
{}
inline
void
SetIntArrayRegion
(
jintArray
,
jsize
,
jsize
,
const
jint
*
)
{}
inline
void
SetLongArrayRegion
(
jlongArray
,
jsize
,
jsize
,
const
jlong
*
)
{}
inline
void
SetFloatArrayRegion
(
jfloatArray
,
jsize
,
jsize
,
const
jfloat
*
)
{}
inline
void
SetDoubleArrayRegion
(
jdoubleArray
,
jsize
,
jsize
,
const
jdouble
*
)
{}
static
int
m_arrayLength
;
};
#define JNI_COMMIT 1
#define JNI_ABORT 2
#endif
src/kandroidextras/jni/jniarray.h
View file @
82c4fe51
...
...
@@ -7,18 +7,44 @@
#ifndef KANDROIDEXTRAS_JNIARRAY_H
#define KANDROIDEXTRAS_JNIARRAY_H
#include
"jnitypetraits.h"
#include
<QAndroidJniEnvironment>
#include
<QAndroidJniObject>
namespace
KAndroidExtras
{
///@cond internal
namespace
Internal
{
/** Basic type array type traits. */
template
<
typename
T
>
struct
array_trait
{};
#define MAKE_ARRAY_TRAIT(base_type, type_name) \
template <> struct array_trait<base_type> { \
typedef base_type ## Array type; \
static inline type newArray(JNIEnv *env, jsize size) { return env->New ## type_name ## Array(size); } \
static inline base_type* getArrayElements(JNIEnv *env, type array, jboolean *isCopy) { return env->Get ## type_name ## ArrayElements(array, isCopy); } \
static inline void releaseArrayElements(JNIEnv *env, type array, base_type *data, jint mode) { return env->Release ## type_name ## ArrayElements(array, data, mode); } \
static inline void setArrayRegion(JNIEnv *env, type array, jsize start, jsize length, const base_type *data) { env->Set ## type_name ## ArrayRegion(array, start, length, data); } \
};
MAKE_ARRAY_TRAIT
(
jboolean
,
Boolean
)
MAKE_ARRAY_TRAIT
(
jbyte
,
Byte
)
MAKE_ARRAY_TRAIT
(
jchar
,
Char
)
MAKE_ARRAY_TRAIT
(
jshort
,
Short
)
MAKE_ARRAY_TRAIT
(
jint
,
Int
)
MAKE_ARRAY_TRAIT
(
jlong
,
Long
)
MAKE_ARRAY_TRAIT
(
jfloat
,
Float
)
MAKE_ARRAY_TRAIT
(
jdouble
,
Double
)
#undef MAKE_ARRAY_TRAIT
/** Meta function for retrieving a JNI array .*/
template
<
typename
Container
,
typename
Value
>
struct
FromArray
{};
template
<
typename
Container
,
typename
Value
,
bool
is_basic
>
struct
FromArray
{};
template
<
typename
Container
>
struct
FromArray
<
Container
,
QAndroidJniObject
>
struct
FromArray
<
Container
,
QAndroidJniObject
,
false
>
{
inline
auto
operator
()(
const
QAndroidJniObject
&
array
)
const
{
...
...
@@ -38,7 +64,7 @@ struct FromArray<Container, QAndroidJniObject>
};
template
<
typename
Container
>
struct
FromArray
<
Container
,
QString
>
struct
FromArray
<
Container
,
QString
,
false
>
{
inline
auto
operator
()(
const
QAndroidJniObject
&
array
)
const
{
...
...
@@ -57,15 +83,39 @@ struct FromArray<Container, QString>
}
};
// TODO specializations for basic types
// specializations for basic types
template
<
typename
Container
,
typename
Value
>
struct
FromArray
<
Container
,
Value
,
true
>
{
typedef
array_trait
<
Value
>
_t
;
inline
auto
operator
()(
const
QAndroidJniObject
&
array
)
const
{
if
(
!
array
.
isValid
())
{
return
Container
{};
}
const
auto
a
=
static_cast
<
typename
_t
::
type
>
(
array
.
object
());
QAndroidJniEnvironment
env
;
const
auto
size
=
env
->
GetArrayLength
(
a
);
Container
r
;
r
.
reserve
(
size
);
auto
data
=
_t
::
getArrayElements
(
env
,
a
,
nullptr
);
std
::
copy
(
data
,
data
+
size
,
std
::
back_inserter
(
r
));
_t
::
releaseArrayElements
(
env
,
a
,
data
,
JNI_ABORT
);
return
r
;
}
};
}
///@endcond
namespace
Jni
{
/** Convert a JNI array to a C++ container.
* Container value types can be any of QAndroidJniObject, QString or a basic JNI type.
*/
template
<
typename
Container
>
constexpr
__attribute__
((
__unused__
))
Internal
::
FromArray
<
Container
,
typename
Container
::
value_type
>
fromArray
=
{};
template
<
typename
Container
>
constexpr
__attribute__
((
__unused__
))
Internal
::
FromArray
<
Container
,
typename
Container
::
value_type
,
Jni
::
is_basic_type
<
typename
Container
::
value_type
>::
value
>
fromArray
=
{};
}
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment