简体   繁体   中英

How to call a method of a subclass / child class of an Java Object passed to JNI `jobject`

I have:

public class MyEntity {
    private String _myEntityType;

    public String get_myEntityType() {
        return _myEntityType;
    }

    public void set_myEntityType(String _myEntityType) {
        this._myEntityType = _myEntityType;
    }
}  

Then :

public class MyObjectEntity extends MyEntity {
    public MyObjectEntity() {
        super();
    }

    private String _myObjectDescription;

    public String get_myObjectDescription() {
        return _myObjectDescription;
    }

    public void set_myObjectDescription(String _myObjectDescription) {
        this._myObjectDescription = _myObjectDescription;
    }
}  

Now I start getting into JNI.

public class MyPers {

    // Load the 'my-pers-lib' library on application startup.
    static {
        System.loadLibrary("my-pers-lib");
    }

    public native Long myPersInit(MyEntity myEntity);
}  

Then :

#include <jni.h>

#include <android/log.h>

extern "C"
JNIEXPORT jobject JNICALL
Java_my_ca_my_1gen_1lib_1pers_c_1libs_1core_RevPers_myPersInit(JNIEnv *env, jobject instance,
  jobject myEntity) {

    jclass myEntityClazz = env->GetObjectClass(myEntity);

    /** START GET STRING **/

    const char *myEntityType;

    // and the get_myObjectDescription() method
    jmethodID get_myObjectDescription = env->GetMethodID
    (myEntityClazz, "get_myObjectDescription", "()Ljava/lang/String;");

    // call the get_myObjectDescription() method
    jstring s = (jstring) env->CallObjectMethod
    (myEntity, get_myObjectDescription);

    if (s != NULL) {
        // convert the Java String to use it in C
        myEntityType = env->GetStringUTFChars(s, 0);
        __android_log_print(ANDROID_LOG_INFO, "MyApp", "get_myObjectDescription :  %s\n",
            myEntityType);

        env->ReleaseStringUTFChars(s, myEntityType);
    }

    /** END GET STRING **/

    return myEntityGUID;

}  

I start it all up :

MyObjectEntity myObjectEntity = new MyObjectEntity();
myObjectEntity.set_myObjectDescription("A Good Day To Find Answers To Life's Important Questions.");

MyPers revPers = new MyPers();

Log.v("MyApp", "GUID : " + myPers.myPersInit(myObjectEntity));  

The error I get is :

JNI CallObjectMethodV called with pending exception java.lang.NoSuchMethodError: no non-static method "Lmy_app/MyEntity;.get_myObjectDescription()Ljava/lang/String;"  

QUESTION

How can I go about calling a method of a subclass / child class of an Java Object passed to JNI jobject , myEntity in this case?

extern "C"
JNIEXPORT jobject JNICALL
Java_myPersInit(JNIEnv *env, jobject instance, jobject myEntity)  

Thank you all in advance.

How can I go about calling a method of a subclass / child class of an Java Object passed to JNI jobject, myEntity in this case?

The question does not make sense. Objects do not have subclasses, classes do. Whatever the class of a given object happens to be defines the methods that you may invoke on that object. You seem to be trying to ask how to invoke methods of a subtype of the declared type of the native method parameter, but the premise of such a question runs counter to the actual fact that you do so exactly the same way you invoke any other instance method from JNI.

Consider: in Java, you would downcast to the subtype and then, supposing the cast succeeded, you would invoke the wanted method normally. In JNI, on the other hand, object references are not differentiated by pointed-to object type (they are all jobject s), so no casting is involved; you just go straight to invoking the wanted method normally.

Of course, a JNI error will occur if the class of the target object does not provide such a method. Whether it's a good idea to do what you describe is an entirely separate question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM