Как вызвать метод подкласса / дочернего класса Java-объекта, переданного в JNI `jobject` - PullRequest
0 голосов
/ 25 июня 2018

у меня есть:

public class MyEntity {
    private String _myEntityType;

    public String get_myEntityType() {
        return _myEntityType;
    }

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

Тогда:

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

Теперь я начинаю проникать в 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);
}  

Тогда:

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

}  

Я запускаю все это:

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

Я получаю ошибку:

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

ВОПРОС

Как я могу вызвать метод подкласса / дочернего класса Java-объекта, передаваемого в JNI jobject, myEntity в этом случае?

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

Спасибо всем заранее.

1 Ответ

0 голосов
/ 25 июня 2018

Как я могу вызвать метод подкласса / дочернего класса Java-объекта, переданного в JNI jobject, в данном случае myEntity?

Вопрос не имеет смысла. Объекты не имеют подклассов, классы имеют.Каким бы ни был класс данного объекта, он определяет методы, которые вы можете вызывать для этого объекта.Вы, кажется, пытаетесь спросить, как вызывать методы подтипа объявленного типа параметра native-метода, но предпосылка такого вопроса противоречит тому факту, что вы делаете это точно так же, как вы вызываете любой другой экземплярМетод из JNI.

Учтите: в Java вы должны были опуститься до подтипа, а затем, предположив, что приведение прошло успешно, вы обычно вызываете требуемый метод.В JNI, с другой стороны, ссылки на объекты не различаются по указанным типам объектов (все они jobject s), поэтому приведение не выполняется;вы просто переходите к обычному вызову требуемого метода.

Конечно, произойдет ошибка JNI, если класс целевого объекта не предоставит такой метод.Является ли хорошей идеей делать то, что вы описываете, - это совершенно отдельный вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...