Как мне справиться с проблемой получения methodID в jni? - PullRequest
1 голос
/ 17 января 2020

Я пытаюсь вызвать метод java из JNI.

Для этого я сделал следующее:

Это мой java класс

data class MyJavaClass(var keyId: String = ""): HashMap<String,Any>(){
     fun getSpecialObjects(): HashMap<String, Array<SpecialObject>>{
             val result = HashMap<String, Array<SpecialObject>>()
             forEach { (k, v) ->
                try {
                   val vJson = gson.toJson(v)
                   val item: ArrayList<SpecialObject> = gson.fromJson(vJson, type)
                   result[k] = item.toTypedArray()
                } catch (e: Exception) {
                  //this is OK, i'm filtering the right values
             }
            }
            return result
     }
    }

Это мой класс-обёртка

    class Wrapper {
              companion object {

              // Used to load the 'native-lib' library on application startup.
             init {
                System.loadLibrary("wrapper")
             }
           }
         external fun doSomething(objects: Array<MyJavaClass>): HashMap<String,Any>
     }

Это моё определение jni

  extern "C" JNIEXPORT jobject JNICALL
Java_com_mypackagename_wrapper_Wrapper_doSomthing(JNIEnv *env, jobject jobj, jobjectArray arrayOfMyJavaClass ) {

    auto objectArrayLength = env->GetArrayLength(arrayOfMyJavaClass);
    std::string className = "com/mypackagename/path/to/MyJavaClass";
    jclass clzz = findClass(env, className);
    jfieldID keyIdFieldId = env->GetFieldID(clzz, "keyId", "Ljava/lang/String;");
    jmethodID  getSpecialObjectsMethodID = env->GetMethodID(clzz, "getSpecialObjects", "()Ljava/util/HashMap;");

    for (int i = 0; i < objectArrayLength; i++) {
        auto object = env->GetObjectArrayElement(arrayOfMyJavaClass, i);

        auto key = env->GetObjectField(object, keyIdFieldId);
        auto map = env->CallObjectMethod(object, getSpecialObjectsMethodID); <-- it falls here
    }
    return NULL;
}

мой код находится в следующей строке:

auto map = env->CallObjectMethod(object, getSpecialObjectsMethodID);

Я запустил javap -s MyJavaClass и получил следующий результат:

public final class com.mypackagename.path.to.MyJavaClass extends java.util.HashMap<java.lang.String, java.lang.Object> {
  public final java.lang.String getKeyId();
    descriptor: ()Ljava/lang/String;

  public final void setKeyId(java.lang.String);
    descriptor: (Ljava/lang/String;)V

  public final java.util.HashMap<java.lang.String, com.mypackagename.path.to.SpecialObject[]> getSpecialObjects();
    descriptor: ()Ljava/util/HashMap;

  public final boolean isValid();
    descriptor: ()Z

  public com.mypackagename.path.to.MyJavaClass();
    descriptor: ()V

  public java.lang.Object getOrDefault(java.lang.String, java.lang.Object);
    descriptor: (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;

  public final java.lang.Object getOrDefault(java.lang.Object, java.lang.Object);
    descriptor: (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;

  public boolean containsKey(java.lang.String);
    descriptor: (Ljava/lang/String;)Z

  public final boolean containsKey(java.lang.Object);
    descriptor: (Ljava/lang/Object;)Z

  public java.lang.Object get(java.lang.String);
    descriptor: (Ljava/lang/String;)Ljava/lang/Object;

  public final java.lang.Object get(java.lang.Object);
    descriptor: (Ljava/lang/Object;)Ljava/lang/Object;

  public java.lang.Object remove(java.lang.String);
    descriptor: (Ljava/lang/String;)Ljava/lang/Object;

  public final java.lang.Object remove(java.lang.Object);
    descriptor: (Ljava/lang/Object;)Ljava/lang/Object;

  public boolean remove(java.lang.String, java.lang.Object);
    descriptor: (Ljava/lang/String;Ljava/lang/Object;)Z

  public final boolean remove(java.lang.Object, java.lang.Object);
    descriptor: (Ljava/lang/Object;Ljava/lang/Object;)Z

  public java.util.Set getEntries();
    descriptor: ()Ljava/util/Set;

  public final java.util.Set<java.util.Map$Entry<java.lang.String, java.lang.Object>> entrySet();
    descriptor: ()Ljava/util/Set;

  public java.util.Set getKeys();
    descriptor: ()Ljava/util/Set;

  public final java.util.Set<java.lang.String> keySet();
    descriptor: ()Ljava/util/Set;

  public java.util.Collection getValues();
    descriptor: ()Ljava/util/Collection;

  public final java.util.Collection<java.lang.Object> values();
    descriptor: ()Ljava/util/Collection;

  public int getSize();
    descriptor: ()I

  public final int size();
    descriptor: ()I
}

Однако мой код падает, поскольку он утверждает, что methodID для getSpecialObjectsMethodID равен нулю .

Что я делаю не так?

...