简体   繁体   English

如何通过引用将列表从 Java 传递给 JNI C++ 作为向量?

[英]How to pass List from Java to JNI C++ as vector by ref?

I am fresh in C++ and JNI我刚接触 C++ 和 JNI

Flow should be like this流量应该是这样的

From Java I pass a empty List to JNI, JNI invoke method loadData(std::vector<int>) from MyClass and this method fill my list with a data.从 Java 中,我将一个空List传递给 JNI,JNI 从MyClass调用方法loadData(std::vector<int>)并且此方法用数据填充我的列表。

So, question is所以,问题是

I have我有

class MyClass {
public:
MyClass();
~MyClass();

void loadData(std::vector<int> & vector);
};


void MyClass::loadData(std::vector<int> & vector)
{
const int size = 10;

vector.resize(size);

for (int i = 0; i < size; ++i) {
    vector.push_back(4);
}
}

This is my method that I wrote in pure C++ and now I need to use it from Java like this这是我用纯 C++ 编写的方法,现在我需要像这样从 Java 中使用它

public native void fillListWithData(List<Integer> list);

So, I wrote such method in JNI to associate them所以,我在JNI中写了这样的方法来关联它们

extern "C" JNIEXPORT void JNICALL
Java_com_google_ar_core_examples_java
_helloar_HelloArActivity_fillListWithData(
    JNIEnv *env,
    jobject /* this */,
    jobject input
) {
myClass->loadData("HERE I NEED TO PASS MY " input);
}

And here how I should to invoke this method在这里我应该如何调用这个方法

public void TEST(){
    List<Integer> list = new ArrayList<>();
    fillListWithData(list);
    Log.e("TAG", "HERE I NEED TO HAVE A LIST WITH FILLED DATA");
}

I can't understand how to pass this list by reference by JNI to C++...我无法理解如何通过 JNI 引用将此列表传递给 C++...

Any ideas appreciate任何想法赞赏

In this case, it's quite simple.在这种情况下,这很简单。 All you have to do is to pass List to your native code and fill it inside JNI part using JNI based access methods您所要做的就是将List传递给您的本机代码并使用基于JNI的访问方法将其填充到JNI部分中

#include <vector>
#include "jni.h"
#include "recipeNo046_FillTheList.h"
using namespace std;

JNIEXPORT void JNICALL Java_recipeNo046_FillTheList_fillTheList
  (JNIEnv *env, jclass cls, jobject obj) {

  vector<int> vect { 1, 2, 3 };

  jclass listClass = env->FindClass("java/util/List");
  if(listClass == NULL) {
    return;                  // alternatively, throw exception (recipeNo019)
  }

  jclass integerClass = env->FindClass("java/lang/Integer");
  if(integerClass == NULL) {
    return;                  // alternatively, throw exception (recipeNo019)
  }

  jmethodID addMethodID = env->GetMethodID(listClass, "add", "(Ljava/lang/Object;)Z");
  if(addMethodID == NULL) {
    return;                  //                 - || -
  }

  jmethodID integerConstructorID = env->GetMethodID(integerClass, "<init>", "(I)V");
  if(integerConstructorID == NULL) {
    return;                  //                 - || -
  }

  for(int i : vect) {
    // Now, we have object created by Integer(i)
    jobject integerValue = env->NewObject(integerClass, integerConstructorID, i);
    if(integerValue == NULL) {
      return;
    }
    env->CallBooleanMethod(obj, addMethodID, integerValue);
  }

  env->DeleteLocalRef(listClass);
  env->DeleteLocalRef(integerClass);

}

Note that you don't have to create List object inside JNI as you already have it there - inside C++ code.请注意,您不必在JNI创建List对象,因为您已经在那里 - 在C++代码中创建了它。 It is passed as argument of native method.它作为native方法的参数传递。

You can find full sample code here:您可以在此处找到完整的示例代码:

https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo046 https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo046

Once you run the code, you can see data from C++ being passed through the List object.运行代码后,您可以看到来自C++数据通过List对象传递。

> make test
/Library/Java/JavaVirtualMachines/jdk-12.0.1.jdk/Contents/Home/bin/java -Djava.library.path=:./lib -cp target recipeNo046.FillTheList
library: :./lib
1
2
3

The answer mentioned by @Oo.oO may seem to work in Windows 10, But is not in the case with Windows 8. @Oo.oO 提到的答案似乎适用于 Windows 10,但不适用于 Windows 8。
Windows 8 does'nt support any containers from Cpp Libraries to work with. Windows 8 不支持使用 Cpp 库中的任何容器。
The Reported Error would be - " %1 is not a valid Win32 Application "报告的错误将是 - “%1 不是有效的 Win32 应用程序”
This occurs while running the Java Program.这发生在运行 Java 程序时。
The dll file generated here seem to be the issue.此处生成的 dll 文件似乎是问题所在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM