2016-10-10 3 views
1

Из-за проблем с безопасностью я хотел бы связать все библиотеки статически, включая мою собственную библиотеку, содержащую функцию JNI_OnLoad. Я читал, что можно связать библиотеку JNI статически (http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html#library_version), но я не могу сделать это с помощью Android Studio. Является ли это возможным?Статическая библиотека Android NDK cmake JNI

Вот что у меня есть.

В Java коде:

System.loadLibrary("testlibrary"); 

В CMake Makefile:

add_library(testlibrary 
     STATIC 
     ${mysources}) 
target_link_libraries(testlibrary) 

В файле C++:

extern "C" { 
EXPORT 
JNIEXPORT jint JNICALL JNI_OnLoad_testlibrary(JavaVM *vm, void *reserved) { 
    ... 
    return JNI_VERSION_1_8; 
} 

Когда построен с Android Studio приложения не удается, потому что он пытается найти * .so файл библиотеки:

java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/xxx-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libtestlibrary.so"

+0

'target_link_libraries' принимает по меньшей мере 2 аргумента: исполняемый файл/библиотеку и другую библиотеку для связи с ним. В вашем коде вы передаете только один аргумент. – Tsyvarev

+0

Какие проблемы безопасности вы пытаетесь решить, используя статическую библиотеку вместо динамической? Статические библиотеки, во всяком случае, содержат больше информации, чем общий, не менее. –

+0

Я пытаюсь избежать случаев, когда кто-то решает переопределить функции внутри разделяемых библиотек с поддельными из пользовательской библиотеки. – jozols

ответ

0
System.loadLibrary("testlibrary"); 

Эта линия пытается загрузить libtestlibrary.so, и, очевидно, он не был построен и упаковывают в APK, так как библиотека с этим именем статично:

add_library(testlibrary 
     STATIC 
     ${mysources}) 

Здесь вы описали цель libtestlibrary.a , который не загружается и может быть связан только с загружаемым .so. Поэтому для достижения желаемого результата вы должны объявить testlibrary как общий, а затем связать его с другими статическими библиотеками. В результате вы получите одну монолитную общую библиотеку, которая может быть загружена в адресное пространство программы. Например,

add_library(testlibrary SHARED ${mysources}) 
add_library(lib1 STATIC ${lib1_src}) 
add_library(lib2 STATIC ${lib2_src}) 
... 
target_link_libraries(testlibrary lib1 lib2 ...) 
+0

Это то, что у меня есть в настоящее время - общая библиотека, связывающая несколько статических библиотек. Но этого я не хотел. Я думал, что может быть способ разместить весь собственный код внутри статической библиотеки, избегая совместного использования. Как было предложено в ссылке I: 'Если библиотека L статически связана, то при первом вызове System.loadLibrary (" L ") или эквивалентном API функция JNI_OnLoad_L будет вызываться с теми же аргументами и ожидаемым возвращаемым значением, что и указанный для функции JNI_OnLoad. ' – jozols

+0

@jozols Похоже, эта цитата посвящена функции, которая не поддерживается Android на данный момент. Только общие библиотеки имеют смысл в APK и могут быть распознаны во время исполнения Android. – Sergio

+1

необходимо, чтобы он был загружен, как DLL для Windows. – Gerry