Я пытаюсь вызвать метод 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 равен нулю .
Что я делаю не так?