Как реализовать отображение от типа к объекту вызова метода с использованием шаблонов C ++?

Я хотел бы разработать (еще одну) оболочку для Java-массивов в коде JNI с использованием шаблонов C ++. Основная цель — улучшить свои навыки программирования шаблонов на C ++.

Я компилирую код, используя Android NDK (компилятор Clang 6.0.2)

Что мне удалось сделать до сих пор:

#include <jni.h>

template <typename T>
struct TypeToObjectType;

template <>
struct TypeToObjectType<jbyteArray>
{
typedef jbyte type;
};

template <>
struct TypeToObjectType<jintArray>
{
typedef jint type;
};

template <typename javaArrayT, typename nativeT>
class Java_array{
JNIEnv *env;
jboolean is_copy;
jsize array_len;

javaArrayT array;
typename TypeToObjectType<javaArrayT>::type *array_elements;

public:
Java_array(JNIEnv *_env, javaArrayT _array)
: env(_env)
, array(_array)
, array_len(-1)
{
array_elements = env->GetByteArrayElements(array, &is_copy);  //TODO: make it resolving automatically to other primitives
}

~Java_array() {
env->ReleaseByteArrayElements(array, array_elements, JNI_ABORT);
}

jsize len(){
if (array_len < 0)
array_len = env->GetArrayLength(array);
return array_len;
}

operator nativeT* () const {
return reinterpret_cast<nativeT*>(array_elements);
};
};

Это не работает для int[], float[] и другие массивы, кроме byte[], так как этот класс вызывает GetByteArrayElements,

я использую struct TypeToObjectType установить отображение jbyteArray -> jbyte, jintArray -> jint,

В этом отображении отсутствует часть типа Java -> JEnv вызовы метода, то есть jbyteArray -> (GetByteArrayElements, ReleaseByteArrayElements), jintArray -> (GetIntArrayElements, ReleaseIntArrayElements) `

Как мне это сделать?

Как я могу улучшить свой код, используя функции из C ++ 11, C ++ 14?

1

Решение

Вы можете добавить указатель на членов вашей черты.

template <>
struct TypeToObjectType<jbyteArray>
{
typedef jbyte type;
static constexpr jbyte * (JNIEnv::* const GetElements)(jbyteArray, jboolean *) = &JNIEnv::GetByteArrayElements;
static constexpr void (JNIEnv::* const ReleaseElements)(jbyteArray, jbyte *, decltype(JNI_ABORT)) = &JNIEnv::ReleaseByteArrayElements;
};

template <>
struct TypeToObjectType<jintArray>
{
typedef jint type;
static constexpr jint * (JNIEnv::* const GetElements)(jintArray, jboolean *) = &JNIEnv::GetIntArrayElements;
static constexpr void (JNIEnv::* const ReleaseElements)(jintArray, jint *, decltype(JNI_ABORT)) = &JNIEnv::ReleaseIntArrayElements;
};

Который вы называете через немного другой синтаксис

Java_array(JNIEnv *_env, javaArrayT _array)
: env(_env)
, array(_array)
, array_len(-1)
{
array_elements = (env->*TypeToObjectType<javaArrayT>::GetElements)(array, &is_copy);
}

~Java_array() {
(env->*TypeToObjectType<javaArrayT>::ReleaseElements)(array, array_elements, JNI_ABORT);
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]