SIGSEGV с использованием ARCore с собственным приложением для Android

Я хочу использовать ARCore внутри собственного приложения для Android на С++. Поэтому мне нужны env и контекст JNI. Оболочка JNI предоставляется внутри структуры android_app, но без контекста. Я нашел решение для получения контекста Android с помощью виртуальной машины. Но нет действительного указателя на контекст.

JNIEnv *env = 0; // env: 0x0000007ed9bdb0c8
jobject contextObj = 0; // env: 0x0000000000000011

_pAndroidApp->activity->vm->AttachCurrentThread(&env, NULL);

jclass activityClass = env->FindClass("android/app/NativeActivity");  // activityClass: 0x0000000000000001

// or use: jclass activityClass = env->GetObjectClass(_pAndroidApp->activity->clazz);

jmethodID contextMethod = env->GetMethodID(activityClass, "getApplicationContext", "()Landroid/content/Context;"); // contextMethod: 0x000000709660f0

contextObj = env->CallObjectMethod(_pAndroidApp->activity->clazz, contextMethod);

После этого я хочу создать сеанс ARCore:

ArSession_create(_pAndroidApp->activity->env, contextObj, &ar_session_);

Указатель на contextObj кажется неправильным. На самом деле, activityClass тоже кажется неверным. Результатом создания сеанса является SIGINT (сигнал SIGINT).


person Tobias Schwandt    schedule 09.01.2018    source источник
comment
Спасибо за эту ссылку. Я уже видел это, но моя проблема в явно недопустимом указателе. Может кто-то еще сталкивается с такой же проблемой.   -  person Tobias Schwandt    schedule 09.01.2018
comment
FindClass на самом деле не нужно. Вместо этого вы можете использовать env->GetObjectClass(_pAndroidApp->activity->clazz).   -  person Michael    schedule 09.01.2018
comment
Это правда. Я обновил вопрос. Но проблема все еще существует.   -  person Tobias Schwandt    schedule 09.01.2018
comment
что такое _pAndroidApp->activity->clazz? Это должен быть экземпляр объекта, а не класс.   -  person Non-maskable Interrupt    schedule 09.01.2018
comment
Это ссылка на экземпляр NativeActivity, созданный системой.   -  person Tobias Schwandt    schedule 09.01.2018
comment
Для чего именно вам нужен Context? Чтобы создать ARCore Session? Разве вы не можете просто передать _pAndroidApp->activity->clazz вместо этого, так как NativeActivity это Context?   -  person Michael    schedule 09.01.2018
comment
Да, это должно быть возможно, но это не сработало для меня. @см. комментарий к первому ответу.   -  person Tobias Schwandt    schedule 10.01.2018


Ответы (1)


Экземпляр активности Java может использоваться в качестве контекста. Я создал сеанс вызова:

ANativeActivity *activity = app->activity;
CHECK(ArSession_create(activity->env, activity->clazz, &ar_session_) == AR_SUCCESS);
CHECK(ar_session_);

ArConfig* ar_config = nullptr;
ArConfig_create(ar_session_, &ar_config);
CHECK(ar_config);

const ArStatus status = ArSession_checkSupported(ar_session_, ar_config);
CHECK(status == AR_SUCCESS);

CHECK(ArSession_configure(ar_session_, ar_config) == AR_SUCCESS);

ArConfig_destroy(ar_config);

ArFrame_create(ar_session_, &ar_frame_);
CHECK(ar_frame_);

Помните, что создание сеанса может вызвать некоторые исключения Java для таких вещей, как неподдерживаемый телефон или неустановленное сопутствующее приложение. Это приведет к тому, что код возврата из ArSession_create() будет не AR_SUCCESS, а чем-то вроде AR_UNAVAILABLE_ARCORE_NOT_INSTALLED. В этом случае утверждение, вероятно, не лучший выход, а скорее отображение сообщения пользователю.

person Clayton Wilkinson    schedule 09.01.2018
comment
Указатель на app-›activity-›clazz — 0x0000000000001f1a. Это правильно? Потому что, если я сделаю это по-вашему, я получу SIGSEGV (сигнал SIGSEGV: неверный адрес (адрес ошибки: 0x2)). - person Tobias Schwandt; 10.01.2018
comment
clazz — это не указатель, а объект JVM, поэтому низкое значение меня не удивляет. Я постараюсь опубликовать полный пример, который поможет отследить вашу проблему. - person Clayton Wilkinson; 10.01.2018
comment
Это было бы чудесно. Благодарю вас! - person Tobias Schwandt; 11.01.2018
comment
Я нашел решение, создав новую среду для текущего потока и определив контекст приложения как глобальную ссылку. Теперь это работает. - person Tobias Schwandt; 17.01.2018