Android NDK: две готовые общие библиотеки, но одна из них зависит от другой.

Я пишу приложение для Android, которое использует две предварительно созданные общие библиотеки (A и B). Обе библиотеки настроены для работы с архитектурами armeabi и armeabi-v7a.

Первая готовая библиотека A — это libsodium. Вторая готовая библиотека, B, — это библиотека Rust, зависящая от libsodium. При компиляции предварительно собранной библиотеки Rust в качестве зависимости используется libsodium.

Прямо сейчас я хочу использовать две готовые библиотеки, A и B, в своем приложении для Android. Загрузка A с помощью System.loadLibrary() работает отлично. Но когда я загружаю B, возникает ошибка, что B не может найти метод, определенный в A:

java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "crypto_sign_ed25519_detached" referenced by "libB.so"...

Мой Android.mk выглядит следующим образом:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := sodium
LOCAL_SRC_FILES := ../jniLibs/$(TARGET_ARCH_ABI)/libsodium.so
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/sodium.h $(LOCAL_PATH)/include/sodium/
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := rust
LOCAL_SRC_FILES := ../jniLibs/$(TARGET_ARCH_ABI)/librust.so
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/sodium.h $(LOCAL_PATH)/include/sodium/
LOCAL_SHARED_LIBRARIES := sodium
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := rust-manager
LOCAL_SRC_FILES := rust-manager.c
LOCAL_SHARED_LIBRARIES := rust sodium
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/ $(LOCAL_PATH)/include/sodium.h $(LOCAL_PATH)/include/sodium/
include $(BUILD_SHARED_LIBRARY)

Файл rust-manager.c — это моя оболочка C, созданная с использованием javah, которая содержит функции C, которые отображают мои собственные функции Java в библиотеку Rust, но я думаю, что на данный момент это незначительно. Любая помощь приветствуется!


person Raed M    schedule 25.11.2015    source источник
comment
Я так понимаю, вы уже загрузили библиотеку А при загрузке библиотеки Б? Можете ли вы попробовать arm-linux-androideabi-nm -D libA.so | grep crypto_sign_ed25519_detached и аналогично для libB.so? (Вы найдете двоичный файл nm в NDK/toolchains/arm-linux-androideabi-4.*/prebuilt/*/bin.)   -  person mstorsjo    schedule 25.11.2015
comment
Правильно, A загружается раньше B. Только что запустил nm и получил следующие результаты: T crypto_sign_ed25519_detached for libA.so U crypto_sign_ed25519_detached for libB.so Есть идеи, что это значит?   -  person Raed M    schedule 25.11.2015
comment
Я предполагаю, что у первого был ненулевой шестнадцатеричный адрес, напечатанный перед T, а у второго было пустое место перед U? Это просто означает, что в libA.so есть определение символа, а в libB.so есть неопределенный символ с таким именем. Так что, учитывая это, это кажется правильным.   -  person mstorsjo    schedule 25.11.2015
comment
О, интересно. Может ли это означать, что libB был сконфигурирован неправильно или что могла произойти какая-то нежелательная оптимизация, из-за которой этот метод был исключен из конечного объекта?   -  person Raed M    schedule 25.11.2015
comment
Нет, это означает, что libB использует эту функцию (или переменную), а libA предоставляет ее - что все кажется правильным, как и должно быть. Вопрос в том, почему он не найден, когда вы уже загрузили libA при попытке загрузить libB.   -  person mstorsjo    schedule 25.11.2015


Ответы (1)


После нескольких дней работы проблема заключалась в версии libsodium, которую я использовал (1.0.6). Я обнаружил, что неопределенные символы при запуске ndk-build зависят от используемой версии. Использование libsodium v1.0.3 решило мои проблемы!

person Raed M    schedule 27.11.2015