Вызов функции класса Java из Какао с JNI - PullRequest
2 голосов
/ 11 февраля 2011

Я действительно пытаюсь понять, как я могу вызвать функцию Java из Objective-C, используя JNI.

Мне следует начать с того, что я ничего не знаю о Java, но очень хорошо знаком с Obj-C. У меня есть один класс Java с одним методом, который мне нужно вызывать из моего пакета приложений. Jar находится внутри папки Resources в комплекте, и у меня NSJavaRoot установлено на Content/Resources, NSJavaNeeded проверено и NSJavaPath содержит имена 2 файлов jar (основная и одна зависимость).

Я запускаю виртуальную машину с помощью вызова JNI_CreateJavaVM, а затем пытаюсь найти класс с помощью NSClassFromString, что кажется неправильным, но это единственный метод, который я нашел в своем поиске. Я считаю, что этот метод является правильным при использовании устаревшего моста Java, но я не могу найти никаких примеров или ссылок, которые используют JNI.

Мой класс Java выглядит так:

package foo;

public class bar {

    public function dostuff() {

    }

}

Мне нужно вызвать dostuff() один раз как часть потока приложения. У кого-нибудь есть идеи как это сделать?

Спасибо, J

1 Ответ

12 голосов
/ 11 апреля 2011

Поскольку JavaBridge устарел, вам придется делать все это с JNI.В MacOS вы захотите добавить JavaVM.framework в ваш проект, и из ваших исходных файлов искомый заголовок будет:

#import <JavaVM/jni.h>

Далее вам нужно настроить JavaVM.Это может быть нетривиально, в зависимости от вашего пути к классу и других требований, но вы на правильном пути, так как эту функцию вы используете для создания JVM:

JNI_CreateJavaVM(JavaVM **pJVM, void **pJNIEnv, void *args);

Далее вы захотитеполучить ссылку на ваш класс foo.bar.Это можно сделать с помощью pJNIEnv, который был передан из JNI_CreateJavaVM.Вам нужно позвонить:

jclass myClass = JNIEnv->FindClass(JNIEnv, "foo/bar"); // Note the slashes replacing the dots...

Если все настроено правильно, вы получите ссылку на свой класс.Предполагая на данный момент, что foo.bar имеет конструктор по умолчанию без параметров, вы можете получить его экземпляр, например:

jobject myFooBar = JNIEnv->NewObject(JNIEnv, myClass);

Теперь вам нужно получить methodID вашего метода doStuff.Для этого вам понадобится сигнатура метода, которую вы можете получить, вызвав javap, например:

% javap -s foo.bar

, который должен выдать вывод, подобный следующему:

Compiled from "bar.java"
public class foo.bar extends java.lang.Object{
public foo.bar();
  Signature: ()V
public void doStuff();
  Signature: ()V
}

Тогда выможете использовать это, чтобы получить methodID, который вам нужно будет вызвать.Вот так:

jmethodID mid = JNIEnv->GetMethodID(JNIEnv, myClass, "doStuff", "()V");

Предполагая, что все эти вещи прошли правильно, вы можете вызвать метод следующим образом:

JNIEnv->CallVoidMethod(JNIEnv, myFooBar, mid);

и метод должен быть вызван.После любого из этих этапов вы, вероятно, захотите проверить у ВМ, было ли исключение.Вы можете проверить, не произошло ли исключение, выполнив это:

if (JNIEnv->ExceptionCheck(JNIEnv))
{
    // Handle the exception...
}

Если вы хотите фактический метод throwable, вы можете получить его, используя метод JNI ExceptionOccurred.

Итак, самое главное: как вы вызываете Java-метод из Какао с JNI.Возможно, вы захотите ознакомиться с документами JNI, особенно с частями о понимании различий между глобальными и локальными ссылками.(т.е. создание ссылок на стороне Какао достаточно долго, чтобы их можно было вызывать за пределами области, в которой они были созданы.) На самом деле, есть целая глава об общих ошибках и ловушках, многие из которых вы попадете.

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

Удачи!

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