Как отобразить Java ArrayListв C ++ Vector> в JniWrapper? - PullRequest
3 голосов
/ 18 октября 2019

У меня есть ArrayList массивов с плавающей точкой, как ArrayList<float[]>, который я хочу отобразить на C ++ Vector<array<float,size>> в JniWrapper.

Я перешел по этой ссылке:

" ВозвращениеArrayList строки из родной Java в JNI"

и внес несколько изменений в код в соответствии с моим требованием.

static jclass java_util_ArrayList;
static jmethodID java_util_ArrayList_;
jmethodID java_util_ArrayList_size;
jmethodID java_util_ArrayList_get;
jmethodID java_util_ArrayList_add;
static thread_local JNIEnv *env;

void java2cpp(jobject arrayList, vector<array<float, 320>> &result) {
    java_util_ArrayList = static_cast<jclass>(env->NewGlobalRef(
            env->FindClass("java/util/ArrayList")));
    java_util_ArrayList_ = env->GetMethodID(java_util_ArrayList, "init", "(I)V");
    java_util_ArrayList_size = env->GetMethodID(java_util_ArrayList, "size", "()I");
    java_util_ArrayList_get = env->GetMethodID(java_util_ArrayList, "get", "(I)Ljava/lang/Object;");
    java_util_ArrayList_add = env->GetMethodID(java_util_ArrayList, "add", "(Ljava/lang/Object;)V");


    jint len = env->CallIntMethod(arrayList, java_util_ArrayList_size);
    result.reserve(len);
    for (jint i = 0; i < len; i++) {
        jfloatArray element = static_cast<jfloatArray>(env->CallObjectMethod(arrayList,
                                                                             java_util_ArrayList_get,
                                                                             i));
        const float *pchars = env->GetFloatArrayElements(element, nullptr);
        result.emplace_back(pchars);
        env->ReleaseFloatArrayElements(element, const_cast<jfloat *>(pchars), 0);
        env->DeleteLocalRef(element);
    }
}

jfloatArray cpp2java(array<float, 320> output) {
    jfloatArray result;
    result = env->NewFloatArray(320);

    float *data;
    data = output.data();

    env->SetFloatArrayRegion(result, 0, 320, data);
    free(data);
    return result;

}

Ошибка:

note: in instantiation of function template specialization 'std::__ndk1::vector<std::__ndk1::array<float, 320>, std::__ndk1::allocator<std::__ndk1::array<float, 320> > >::emplace_back<const float *&>' requested here
        result.emplace_back(pchars);
           ^

Я новичок в разработке JNI Wrappers. Мне нужна помощь в сопоставлении ArrayList<float[]> с Vector<array<float,320>>.

Ответы [ 2 ]

0 голосов
/ 18 октября 2019

Ваш вектор содержит array<float, 320>, но вы передаете ему const float *. Вам необходимо создать массив правильного типа и заполнить его соответствующими данными. Ни в коем случае вы не создаете array<float, 320> и не заполняете его. Прошло много времени с тех пор, как я использовал JNI, поэтому я не помню синтаксис, но вам придется скопировать элементы из jfloatarray в новый array<float, 320>.

Если pchars содержит соответствующие данные, то вы сможете сделать что-то вроде:

const float *pchars = env->GetFloatArrayElements(element, nullptr);
array<float, 320> newArray;
for ( size_t i = 0; i < 320; ++i ) newArray[i] = pchars[i];
result.emplace_back(newArray);
0 голосов
/ 18 октября 2019

тип результата: vector<array<float, 320>>, который передается по ссылке. Однако вы emplace_back a const float*:

const float *pchars = env->GetFloatArrayElements(element, nullptr);
 result.emplace_back(pchars);

Вы можете решить эту проблему, создав массив из данных, указанных pchar, например,

std::array<float, 320> res;
for (int i = 0; i < end; ++i)
     res[i] = pchars[i];
result.emplace_back(res);

Убедитесь, чтопроверка диапазона pchar (конец), к которому вы можете получить доступ за пределами.

...