Returning an arraylist of string from Native java to JNI

前端 未结 1 1997
夕颜
夕颜 2020-12-28 22:25
           ArrayList myArraylist;          

           public ArrayList getData(){
               myArraylist = new ArrayList

        
相关标签:
1条回答
  • 2020-12-28 23:19

    Convert ArrayList to std::vector<std::string>:

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

    Push ArrayList from JNI back to Java

    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).

    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;
    }
    

    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.

    0 讨论(0)
提交回复
热议问题