Объектив C, вызывающий методы Java с использованием JNI

Может ли кто-нибудь показать мне, как вызвать метод Java из Objective C.

Более подробно это то, что я хотел бы сделать

1) Первый вызов со стороны Java к объекту C. Во время этого вызова я хотел бы получить ссылку на объект Java.

2) Позже я хотел бы, чтобы Objective C использовал ссылку, полученную на предыдущем шаге, для вызова методов Java.

Спасибо


person user1216750    schedule 02.03.2012    source источник
comment
Objective C — это правильный надмножество C, поэтому любой код, который у вас есть, работает на C, просто переносите его и запускайте в ObjC.   -  person Perception    schedule 02.03.2012
comment
Что заставляет вас думать, что у меня есть код C. :-)   -  person user1216750    schedule 03.03.2012
comment
На самом деле я знаю, и это один из подходов, который я готов использовать. Но код C, который у меня есть, сложен. Есть много других вещей, которые делаются на C, и есть много взаимосвязей, мне трудно следовать и просто делать то же самое. Также я надеялся сохранить весь код в Objective C.   -  person user1216750    schedule 03.03.2012
comment
Вам не нужно менять код C на Objective-C, просто поместите его в свой проект и вызовите его.   -  person danielbeard    schedule 07.03.2012


Ответы (1)


Следующее, кажется, работает. Он основан на приведенном выше комментарии к примерам C и этой ссылке.

http://urlgrey.net/?p=121

Как говорится в ссылке, не создавайте глобальную переменную для env, вместо этого создайте глобальную переменную jvm, а также создайте глобальную ссылку на свой класс.

Вот как я реализую шаг 1: «1) Первый вызов со стороны Java к объекту C. Во время этого вызова я хотел бы получить ссылку на объект Java».

Сначала объявите глобальную переменную в заголовочном файле для

1) JVM:

JavaVM *jvm;

2) Класс Java:

jclass smartCallbackClass;

3) Объект Java:

jobject smartCallbackObject;

Далее в вызове, который поступает со стороны Java на Objective C, установите значения для этих переменных

1) Для JVM:

(*env)->GetJavaVM(env, &jvm);

2) Для объекта:

smartCallbackObject = (*env)->NewGlobalRef(env, obj);

3) Для класса:

if (smartCallbackClass == NULL) {
    jclass localRefCls = (*env)->FindClass(env,"com/studyisland/nativelibs/smart/responsesdk/interfaces/thin/SMARTResponseThinClient"); 
    if (localRefCls == NULL) {
        NSLog(@"Unable to create a JNI Java Class reference \n");
    }
    //Create a global reference for JNI Java class
    smartCallbackClass = (*env)->NewGlobalRef(env,localRefCls);

    //Delete the local reference as it is no longer needed
    (*env)->DeleteLocalRef(env, localRefCls);

    //Is the global reference created successfully?
    if (smartCallbackClass == NULL) {
        NSLog(@"Unable to create JNI Java class reference \n");
        return 0;
    }       
}

Вот ссылка, откуда я взял код класса

http://java.sun.com/docs/books/jni/html/refs.html

Теперь второй шаг

«2) Позже я хотел бы, чтобы Objective C использовал ссылку, полученную на предыдущем шаге, для вызова методов Java»

Чтобы вызвать из Objective C обратно в Java, вам нужно убедиться, что вызов выполняется в том же потоке, с помощью которого Java вызвала Objective C, поэтому вот код.

-(void)classFailedToStop:(SMARTResponseCallBackEventArg*)anArg{
    JNIEnv *env;
    int attach = (*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL);
    if(attach == 0){
        (*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_4);
        jmethodID method = (*env)->GetMethodID(env, smartCallbackClass, "callback_onStopClassFailed", "()V");
        (*env)->CallVoidMethod(env, smartCallbackObject, method);
    }
    (*jvm)->DetachCurrentThread(jvm);

}

Надеюсь это поможет.

person user1216750    schedule 07.03.2012
comment
Как Java может вызывать Objective-C в проекте Objective-C. Не было вопроса о вызове Java из Obejctive-C. В начале вашего ответа у вас есть первый вызов со стороны Java к цели C? - person Lealo; 19.01.2018