#android #android_ndk #build
Есть библиотека, назовем ее Library.so и инклуды к ней. Без jni. Нужно присоединить ее к проекту. Для этого пишу jni обертку. Собираю все следующим образом (Android.mk): LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := Library LOCAL_SRC_FILES := Library.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := Library_jni LOCAL_SRC_FILES := Library_jni.c LOCAL_LDLIBS += $(LOCAL_PATH)/../libs/armeabi/libLibrary.so LOCAL_C_INCLUDES:= $(LOCAL_PATH)/include include $(BUILD_SHARED_LIBRARY) Все собирается нормально, но при выполнении: static { try{ System.loadLibrary("Library_jni"); }catch(UnsatisfiedLinkError use){ Log.e("JNI","ERROR: Could not load Library_jni.so"); } } сообщение об ошибке выводится. Если не отлавливать, вылетает с исключением: Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1936]: 69 could not load needed library 'libLibrary.so' for 'libLibrary_jni.so' (load_library[1091]: Library 'libLibrary.so' not found) То есть библиотека-обертка не может загрузиться, потому что на найдена основная библиотека. Как я понимаю, она ищется по адресу: $(LOCAL_PATH)/../libs/armeabi/libLibrary.so, но на устройстве, само собой такой папки нет. На устройстве библиотеки лежат в data/data/my.package/lib. Понятно, что она и не найдется. Но при любом другом адресе в LOCAL_LDLIBS линковщик не может найти нужный файл, сборка завершается с ошибкой. Если писать только LOCAL_SHARE_LIBRARIES := libLibrary линковщик не видит реализаций функций из внутренней библиотеки, заголовки видит нормально. Как правильно сослаться на динамическую библиотеку из другой динамической библиотеки, чтобы и на этапе сборки и на этапе выполнения не было ошибок? Можно сделать так, чтобы при сборке библиотека искалась по одному адресу, а при выполнении по другому?
Ответы
Ответ 1
Проблема в том, что загрузчик Андроида автоматически не подгружает зависимости. То есть если библиотека А зависит от библиотеки Б, то пользователь должен самостоятельно грузить библиотеку Б до библиотеки А. Вы можете обойти ограничение, если либо внедрите JNI в основную библиотеку, либо загрузите вручную (dlopen, dlclose) основную библиотеку из вспомогательной.Ответ 2
Все оказалось просто, нужно подгружать библиотеки так: static { try{ System.loadLibrary("Library"); System.loadLibrary("Library_jni"); }catch(UnsatisfiedLinkError use){ use.printStackTrace(); } } Тогда все работает.
Комментариев нет:
Отправить комментарий