Создать статическую библиотеку iOS из проекта robovm (BAD_ACCESS в JNI)

У меня есть большой объем кода Java (только функции расчета, без пользовательского интерфейса), который я хочу повторно использовать в качестве статической библиотеки в iOS. Мой подход состоял в том, чтобы использовать robovm и следовать неофициальному способу создания статической библиотеки, описанному в двух статьях на форуме robovm. : 1 Основной способ и 2 Уточненная версия

Пытаясь выполнить шаги точно так, как описано, я, к сожалению, застрял после создания общей библиотеки со сценарием, связывания библиотеки (.a) в Xcode и успешного создания проекта.

Во время выполнения я вижу, что мой код моста C++ вызывается, но обратные вызовы JNI в библиотеку завершаются с ошибкой BAD_ACCESS. Например, следующая строка дает сбой:

jclass myJavaClass = jniEnv->FindClass("com/test/robovm/bridge/MyJavaRoboCode");

в этом методе:

void callSomethingInJava(const char* arg) {
    // To call into java from your native app, use JNI
    Env* rvmEnv = rvmGetEnv();
    JNIEnv* jniEnv = &(rvmEnv->jni);
    jclass myJavaClass = jniEnv->FindClass("com/test/robovm/bridge/MyJavaRoboCode");
    jmethodID myJavaMethod = jniEnv->GetStaticMethodID(myJavaClass, "callJava", "(Ljava/lang/String;)V");
    jstring argAsJavaString = jniEnv->NewStringUTF(arg);
    jniEnv->CallStaticVoidMethod(myJavaClass, myJavaMethod, argAsJavaString);

}

То же самое верно, если я попытаюсь использовать методы rvmXX напрямую вместо JNI и попытаюсь получить доступ к чему-то в моих классах «Java». Похоже, что rvmEnv не полностью инициализирован. (Я дважды проверил наличие ошибок или опечаток в имени пакета).

Было бы здорово, если бы кто-то уже преуспел в создании общей статической библиотеки из проекта robovm и мог бы поделиться здесь опытом или указать мне правильное направление для решения проблемы.


person wfrank    schedule 29.07.2014    source источник
comment
Привет, wfrank. Я пытался сделать это некоторое время, но мне не удалось заставить Xcode скомпилировать robovm/jni. Две статьи, которые вы описали, звучали многообещающе, но мне интересно, есть ли пример проекта, которым вы могли бы поделиться/порекомендовать?   -  person Wayne Shelley    schedule 12.08.2015


Ответы (1)


Как вы упомянули, вы, вероятно, не закончили инициализацию robovm.

Вам нужно будет создать метод, скажем, initRoboVM(), чтобы несколько отражать основной метод bc.c. Это будет вызываться вашим кодом, когда вы захотите инициализировать robovm. Вам нужно будет передать путь к приложению, который вы можете жестко указать при тестировании.

initRoboVM() потребует некоторых модификаций, а именно, он не должен вызывать основной метод вашего Java-приложения, ну, по крайней мере, это то, что библиотеки с хорошим поведением не должны делать IMO. Он также не должен вызывать rvmShutdown.

person user3161951    schedule 01.08.2014
comment
Спасибо, что помогло. Теперь я могу вызывать Java из Objective C через JNI. Возможно, мне следует указать, что основной метод bc.c вызывается, потому что я не мог удалить основной метод, поскольку компилятор robovm был бы недоволен отсутствующим символом _main в исключении crt0. Теперь мне нужно было отключить мой основной метод приложений iOS и позволить основному методу Robovm запустить мой AppDelegate. В настоящее время я изо всех сил пытаюсь вернуть объект Objc из задания. Объект Java аннотирован @NativeClass... но я думаю, это новый вопрос о переполнении стека. - person wfrank; 13.09.2014