Я задавал этот вопрос в группе Google android-ndk, но не получил никакого ответа.
Я пытаюсь построить общий модуль в независимом проекте, нажав кнопку «Is Library» - затмение.Этот проект предоставляет как c apis, так и java apis.Хотя некоторые из этих apis связаны между собой.(это означает, что не стоит разделять их на 2 проекта) Давайте назовем это common и libcommon.so.
Когда я использую эту библиотеку в другом проекте (предположим, testcommon), я добавляю общий проект в виде библиотеки в eclipse в проводнике проекта -> свойства -> Android -> библиотека -> Добавить.Но это только позволяет мне использовать Java API в библиотеке.
Также я добавляю libcommon.so как PREBUILT_SHARED_LIBRARY в android.mk в проекте testcommon, чтобы я мог получить доступ к c apis.(как показано ниже)
include $(CLEAR_VARS)
LOCAL_MODULE := common-prebuilt
LOCAL_SRC_FILES := ../../common/libs/$(TARGET_ARCH_ABI)/libcommon.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := testCommon
LOCAL_SRC_FILES := testCommon.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../common/jni/include/
LOCAL_SHARED_LIBRARIES := common-prebuilt
include $(BUILD_SHARED_LIBRARY)
Таким образом, ndk-build является успешным, но когда я запускаю его, я получаю следующие ошибки:
[2012-02-29 15:28:20 - testCommon] Error generating final archive:
Found duplicate file for APK: lib/armeabi/libcommon.so
Origin 1: E:\Code\EclipseWorkspace\testCommon\libs\armeabi\libcommon.so
Origin 2: E:\Code\EclipseWorkspace\Common\libs\armeabi\libcommon.so
Я думаю, что оба ссылаются набиблиотека и предварительная сборка разделяемой библиотеки добавьте libcommon.so в проект testcommon.На самом деле, я протестировал, чтобы ссылаться только на библиотеку или добавить предварительно собранную разделяемую библиотеку, они оба скопировали libcommon.so в testcommon.
Вопрос в том, что мне делать, если мне нужна библиотека с c и java apis. (Не только с кодом)
Спасибо
После того, как я прочитал Может ли совместно используемая библиотека вызывать другую совместно используемую библиотеку? , я нашел способ решить эту проблему, но все еще не уверен.
Использование строки ниже в Android.mk вместо PREBUILT_SHARED_LIBRARY также делает работу родной части ибиблиотеки не будут скопированы таким образом.Так что дубликат можно исправить.
LOCAL_LDFLAGS := -L$(LOCAL_PATH)/../../Common/libs/$(TARGET_ARCH_ABI)/ -lcommon
Причина, по которой это не сработало в моем тесте перед тестированием, заключается в том, что даже в этом случае обе библиотеки должны загружаться в Java, а не только libtestCommon.
System.loadLibrary("common"); // I lost this in my before test
System.loadLibrary("testCommon");
Я думаю, теперь мне это понятно.
И LOCAL_SHARED_LIBRARIES, и -L плюс -l должны нормально работать в NDK.
Проблема в том, что когда я вызываю
System.loadLibrary("testCommon")
, он пытается найти файлы в / data / data / $ (путь к приложению) / lib (System.java::loadLibrary --> Runtime.java::loadLibrary -> DexPathList.java::findLibrary), но когда libtestCommon пытается найти свою зависимость libCommon.so, он найдет ее только в / vendor / lib и / system / lib, поскольку
LD_LIBRARY_PATH=/vendor/lib:/system/lib.
Если я сначала вызову System.loadLibrary («common»), dlopen загрузит его в кеш (Linker.c :: alloc_info).Это делает libtestCommon.so загружает libCommon.so успех, я думаю.Так что все работает.
Я также заметил следующие слова в конце SYSTEM-ISSUES.html в ndk-r7:
- Ошибка не позволяет одной общей библиотеке приложения зависетьна другом.Например, если вы соберете libfoo.so и libbar.so для своего приложения и укажите libfoo.so в качестве зависимости для libbar.so в bar / Android.mk (с LOCAL_SHARED_LIBRARIES: = foo), тогда загрузка libbar.so будетвсегда терпит неудачу, даже если вы уже загрузили libfoo.so в ваш процесс.
Здесь немного другое.Если я уже загрузил libfoo.so в моем процессе, libbar.so будет успешным.
Итак, ответ наконец-то:
- Используйте LOCAL_LDFLAGS: = -Lxx -lxx, если вынужны любые общие библиотеки в проекте библиотеки Android.
- Вы должны вызывать System.loadLibrary для всех необходимых общих библиотек.Это также способ использовать другую разделяемую библиотеку в одной библиотеке.
- Путь к библиотекам в / libs / находится по адресу /data/data//lib/.