Как использовать проект библиотеки с c и java apis на Android - PullRequest
2 голосов
/ 01 марта 2012

Я задавал этот вопрос в группе 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/.

Ответы [ 2 ]

0 голосов
/ 31 марта 2014

Я боролся с подобной проблемой.Я хочу создать проект библиотеки Android с использованием Java и C. Я хочу, чтобы Java зависимых проектов могла ссылаться на код библиотеки Java и зависимых проектов в JNI, чтобы иметь возможность ссылаться на C в jni библиотеки.Мне потребовалось два кладжа.Один из них почти идентичен вашему решению:

LOCAL_LDFLAGS := -L$(LOCAL_PATH)/../../Common/libs/$(TARGET_ARCH_ABI)/ -lcommon

Я создал зависимость от фактического расположения библиотечного проекта в файловой системе.Ваша зависимость предполагает, что проект библиотеки Common является дочерним каталогом вашего зависимого TestCommon проекта.

Я также создал Ant-файл build.xml, который копирует заголовочные файлы Cиз проекта библиотеки в каталог jni / include в зависимой папке jni.

С этими двумя ключами я могу заставить все работать.Я бы очень хотел убрать оба клуджа, но не смог найти способ.

0 голосов
/ 25 ноября 2013

В качестве опции вы можете использовать

LOCAL_ALLOW_UNDEFINED_SYMBOLS: = true

в одном из Android.mk и исключить дублирующую библиотеку.

...