为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

皈依舞 2022-12-21 10:58:55
我刚接触 C++ 和 JNI流程应该是这样的我从 Java 向 JNI 传递一个空List值,JNIloadData(std::vector<int>)从中调用方法MyClass,此方法用数据填充我的列表。所以,问题是我有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);}}这是我用纯 C++ 编写的方法,现在我需要像这样从 Java 使用它public native void fillListWithData(List<Integer> list);所以,我在 JNI 中写了这样的方法来关联它们extern "C" JNIEXPORT void JNICALLJava_com_google_ar_core_examples_java_helloar_HelloArActivity_fillListWithData(    JNIEnv *env,    jobject /* this */,    jobject input) {myClass->loadData("HERE I NEED TO PASS MY " input);}在这里我应该如何调用这个方法public void TEST(){    List<Integer> list = new ArrayList<>();    fillListWithData(list);    Log.e("TAG", "HERE I NEED TO HAVE A LIST WITH FILLED DATA");}我不明白如何通过 JNI 将此列表通过引用传递给 C++...任何想法赞赏
查看完整描述

2 回答

?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

在这种情况下,它非常简单。您所要做的就是传递给您的本机代码并使用基于访问的方法List将其填充到内部JNIJNI


#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);


}

请注意,您不必List在内部创建对象,JNI因为您已经在内部C++代码中创建了它。它作为native方法的参数传递。


您可以在此处找到完整的示例代码:


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


运行代码后,您可以看到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


查看完整回答
反对 回复 2022-12-21
?
繁花如伊

TA贡献2012条经验 获得超12个赞

提到的答案似乎适用于 Windows 10,但不适用于 Windows 8。Windows
8 不支持 Cpp 库中的任何容器。
报告的错误将是 - “%1 不是有效的 Win32 应用程序”
,这在运行 Java 程序时发生。
此处生成的 dll 文件似乎是问题所在。

查看完整回答
反对 回复 2022-12-21
  • 2 回答
  • 0 关注
  • 268 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号