将字符串数组列表从 Native java 返回到 JNI [英] Returning an arraylist of string from Native java to JNI

查看:19
本文介绍了将字符串数组列表从 Native java 返回到 JNI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

           ArrayList<String> myArraylist;          

           public ArrayList<String> getData(){
               myArraylist = new ArrayList<String>();          
               myArraylist.add("1267982563");
               myArraylist.add("2345678");
               myArraylist.add("5432789");
               return myArraylist;
           }

如何在JNI端获取上述方法中的每一项,并Push to vector并从JNI返回到JNI层中的其他CPP调用.

How to get the each items from the above method in JNI side and Push to vector and return from the JNI to other CPP calls in the JNI layer.

推荐答案

将 ArrayList 转换为 std::vector:

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

void init() {
  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;)Z");
}

std::vector<std::string> java2cpp(jobject arrayList) {
  jint len = env->CallIntMethod(arrayList, java_util_ArrayList_size);
  std::vector<std::string> result;
  result.reserve(len);
  for (jint i=0; i<len; i++) {
    jstring element = static_cast<jstring>(env->CallObjectMethod(arrayList, java_util_ArrayList_get, i));
    const char *pchars = env->GetStringUTFChars(element, nullptr);
    result.emplace_back(pchars);
    env->ReleaseStringUTFChars(element, pchars);
    env->DeleteLocalRef(element);
  }
}

将 ArrayList 从 JNI 推送回 Java

如果你不在 JNI 中修改这个列表,那么最好的策略是在你的本地代码的某个地方简单地保留一个对它的全局引用.如果您稍作修改,请保持此 jobject 始终是最新的(您可能需要方法 java_util_ArrayList_addjava_util_ArrayList_set).

If you don't modify this list in JNI, then the best strategy would be to simply keep a global reference to it somewhere in your native code. If you modify it a little, keep this jobject always up-to-date (you will probably need the methods java_util_ArrayList_add or java_util_ArrayList_set).

如果您选择从 scratch 向量重建列表,您将展开上述方法:

If you choose to reconstruct the list from scratch the vector, you will unwind the above method:

jobject cpp2java(std::vector<std::string> vector) {
  jobject result = env->NewObject(java_util_ArrayList, java_util_ArrayList_, vector.size());
  for (std::string s: vector) {
    jstring element = env->NewStringUTF(s.c_str());
    env->CallBooleanMethod(result, java_util_ArrayList_add, element);
    env->DeleteLocalRef(element);
  }
  return result;
}

无论如何,在使用 Jni 时要小心线程,始终附加本地线程并在本地线程被销毁之前分离.

At any rate, be careful with threads when you work with Jni, always attach your native threads and detach before the native thread is destroyed.

这篇关于将字符串数组列表从 Native java 返回到 JNI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆