Как я могу вернуть вектор <vector <float>> из JNI? - PullRequest
0 голосов
/ 30 мая 2019

У меня есть функция в C ++:

std::vector<std::vector<float>> const &GetVertices() { return m_Vertices; }

Мне нужно вернуть это значение в Java через JNI.

Итак, из-за того, что мне нужно вернуть vectorиз vector, я думаю, что я должен использовать jobjectArray, например:

extern "C" JNIEXPORT jobjectArray JNICALL
Java_com_google_ar_core_examples_
java_helloar_HelloArActivity_fillListWithData(
    JNIEnv *env,
    jobject /* this */
) 

В Java у меня есть этот метод:

public native Object[] fillListWithData();

Итак,мой вопрос, как конвертировать vector<vector<float>> в jobjectArray?

Я знаю, что есть метод, который может создать jobjectArray:

jobjectArray verticesArr = env->NewObjectArray(verticesVec.size(), WHAT CLASS SHOULD BE HERE?,NULL);

Тогда как можноЯ ввел значения?

Полная реализация класса

extern "C" JNIEXPORT jobjectArray JNICALL
Java_com_google_ar_core_examples_java_
helloar_HelloArActivity_fillListWithData(
    JNIEnv *env,
    jobject /* this */
) {
    //verticesVec
    vector<vector<float>> verticesVec = initializer->GetVertices(); // THIS VECTOR I NEED TO CONVERT TO JOBJECTARRAY
    jobjectArray verticesArr = env->NewObjectArray(verticesVec.size(), WHAT CLASS SHOULD BE HERE?,NULL);

    //HOW TO FILL THE ARRAY HERE??

    return verticesArr;
}

Ответы [ 2 ]

1 голос
/ 31 мая 2019

Вы должны играть с java.util.Vector. Таким образом, вы можете сделать очень простое отображение

(C++ side) vector<vector<float> >  --->  Vector<Vector<Float>> (Java side)

Сам код будет немного уродливым. Помните, что играть с JNI - не совсем приятный опыт (из-за эзотерического синтаксиса).

В любом случае, вы хотите создать все элементы на стороне C++ и передать их обратно Java.

Просто выдержка

  vector<vector<float> > vect {
                                 { 1.1, 1.2, 1.3 },
                                 { 2.1, 2.2, 2.3 },
                                 { 3.1, 3.2, 3.3 }
                              };
  ...
  ...

  jclass vectorClass = env->FindClass("java/util/Vector");
  ...

  jclass floatClass = env->FindClass("java/lang/Float");
  ...

  jmethodID mid = env->GetMethodID(vectorClass, "<init>", "()V");
  jmethodID addMethodID = env->GetMethodID(vectorClass, "add", "(Ljava/lang/Object;)Z");

  // Outer vector
  jobject outerVector = env->NewObject(vectorClass, mid);
  ...

  for(vector<float> i : vect) {

    // Inner vector
    jobject innerVector = env->NewObject(vectorClass, mid);

    for(float f : i) {
      jmethodID floatConstructorID = env->GetMethodID(floatClass, "<init>", "(F)V");
      ...

      // Now, we have object created by Float(f)
      jobject floatValue = env->NewObject(floatClass, floatConstructorID, f);
      ...

      env->CallBooleanMethod(innerVector, addMethodID, floatValue);
    }

    env->CallBooleanMethod(outerVector, addMethodID, innerVector);

  }

  env->DeleteLocalRef(vectorClass);
  env->DeleteLocalRef(floatClass);

Вы можете найти полный пример кода здесь:

https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo045

Как только вы запустите тестирование, вы увидите, что данные на основе C++ были переданы в Java

> make test
/Library/Java/JavaVirtualMachines/jdk-12.0.1.jdk/Contents/Home/bin/java -Djava.library.path=:./lib -cp target recipeNo045.VectorOfVectors
library: :./lib
[1.1,1.2,1.3]
[2.1,2.2,2.3]
[3.1,3.2,3.3]
0 голосов
/ 30 мая 2019

Зависит немного от того, как вы хотите работать с данными в Java, например, добавить больше элементов?Вы не упомянули об этом, поэтому ответ не может быть более конкретным.Но, возможно, вы хотите "java / util / ArrayList" из float.

Следующий ответ должен указать вам правильное направление: вернуть jobjectArray, который содержит списки данных .

Код будет выглядеть аналогично для других типов списков.Небольшой поиск в Интернете предоставит несколько решений.

В случае, если скорость (ЦП / задержка) и объем данных не важны, вместо всей грязной обработки структур данных Java, я обычно рекомендую сериализацию ваших данных в JSON ивернуть как строку.Например, JsonCpp позволяет легко сериализовать типы данных C ++, включая объекты, в JSON, а на стороне Java есть несколько пакетов для десериализации (снова веб-поиск), и многие фреймворки Java поставляются со встроенными инструментами для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...