2017-11-09 14 views
2

Android 앱에서 C++ 공유 라이브러리를 사용하고 싶습니다. Google NDK 샘플의 hello-libs 예제를 따라 가려고했지만 어떻게 든 작동하지 않습니다.Android Studio (cmake)에서 미리 빌드 된 공유 라이브러리 사용

내 라이브러리가 APK에 포함되어 있지 않은 것으로 보입니다. 내가 찾은 모든 자습서는 *.mk - 파일을 사용하고 있지만, cmake을 사용하고 싶습니다.

E/art: dlopen("/data/app/my.package.name-1/lib/arm/libnative-lib.so", RTLD_LAZY) failed: dlopen failed: library "C:/projects/HelloLibs/app/src/main/cpp/../jniLibs/dynamic/lib/armeabi-v7a/libLibrary.so" not foun 
D/AndroidRuntime: Shutting down VM 
E/AndroidRuntime: FATAL EXCEPTION: main 
        Process: my.package.name, PID: 29266 
        java.lang.UnsatisfiedLinkError: dlopen failed: library "C:/projects/HelloLibs/app/src/main/cpp/../jniLibs/dynamic/lib/armeabi-v7a/libLibrary.so" not found 
         at java.lang.Runtime.loadLibrary(Runtime.java:371) 
         at java.lang.System.loadLibrary(System.java:988) 
         at my.package.name.MainActivity.<clinit>(MainActivity.java:11) 
         at java.lang.reflect.Constructor.newInstance(Native Method) 
         at java.lang.Class.newInstance(Class.java:1690) 
         at android.app.Instrumentation.newActivity(Instrumentation.java:1078) 
         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2543) 
         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2771) 
         at android.app.ActivityThread.access$900(ActivityThread.java:177) 
         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1432) 
         at android.os.Handler.dispatchMessage(Handler.java:102) 
         at android.os.Looper.loop(Looper.java:135) 
         at android.app.ActivityThread.main(ActivityThread.java:5912) 
         at java.lang.reflect.Method.invoke(Native Method) 
         at java.lang.reflect.Method.invoke(Method.java:372) 
         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405) 
         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200) 

는 같습니다 : 응용 프로그램을 실행할 때, 나는 다음과 같은 오류가, 다른 사람과 함께 shared-lib을 연결하자마자

# Sets the minimum version of CMake required to build the native library. 
cmake_minimum_required(VERSION 3.4.1) 

# native lib 
add_library(native-lib SHARED 
      native-lib.cpp) 

set(IMPORT_DIR ${CMAKE_SOURCE_DIR}/../jniLibs) 

# shared lib 
add_library(shared-lib SHARED IMPORTED) 
set_target_properties(shared-lib PROPERTIES IMPORTED_LOCATION 
         ${IMPORT_DIR}/dynamic/lib/${ANDROID_ABI}/libLibrary.so) 
target_include_directories(native-lib PRIVATE 
          ${IMPORT_DIR}/dynamic/include) 

# linking libs 
target_link_libraries(native-lib 
         android 
         shared-lib 
         log) 

:

내 CMakeLists.txt입니다 장치에서 라이브러리를 찾을 수 없습니다. 그렇지 않으면 librarie의 경로가 여전히 내 로컬 maschine의 경로 인 것처럼 보입니다.

+0

dlopen ("/ data/app/my.package.name-1/lib/arm/libnative-lib.so", RTLD_LAZY)'해당 디렉토리를 구성 했습니까? 'lib/armeabi-v7a'가되어서는 안 될까요? –

+0

@DanAlbert, 아니오 : 장치에서'lib' 아래 유효한 경로는 ** arm **, ** arm64 **, ** x86 **, ** x86_64 **입니다. 왜 나 한테 묻지 마. –

답변

0

공유 라이브러리 (.so 파일)를 사용하기 위해 CMake를 사용할 필요가 없습니다. src/main/jniLibs 디렉토리의 해당 디렉토리 안에 라이브러리를두기 만하면됩니다. 그런 다음 라이브러리를 직접로드 할 수 있습니다.

Android Studio에서 네이티브 메소드 선언에 오류가 표시 될 수 있지만 앱이 정상적으로 작동합니다.

+0

그러나 어떻게'native-lib-cpp'에서 라이브러리를 사용할 수 있습니까? 공유 라이브러리에는 jni-methods가 없으므로 Android Studio 내부에 작성된 두 번째 라이브러리로 묶고 싶습니다. – Dario

+0

당신은 여전히 ​​jniLibs 폴더에서 target_link_libraries를 사용할 수 있습니다. 단지 디렉토리 만 지정하면됩니다. –

1

미리 작성된 libLibrary.so에는 SONAME이 없습니다. 최신 NDK로이 라이브러리를 다시 빌드 할 수없는 어떤 이유로 든 patchelf 유틸리티를 사용하여 SONAME을 기존 바이너리에 추가 할 수 있습니다.