jni 미리 만들어진 so동적라이브러리 적용

조회수 6084회

안녕하세요

불철주야 개발에 전념하시는 개발자분들 수고가 많으십니다.

일주일동안해봤는데도 안되서 질문을 올리게 되었네요...

결론먼저 말씀드리면 아래와 같은 에러가 발생을 합니다

이미지

위의 에러 로그 중 중요 포인트는 아래의 내용인거 같습니다.

dlopen("data/app-lib/com.example.projecttest/libtest_print.so") failed: dlopen failed: could not load library "libgcc_s.so.1" needed by "libtest_print.so"; caused by library :libgcc_s.so.1" not found

java.lang.unsatisfiedLinkError : dlopen failed: could not load library "libgcc_s.so.1" needed by "libtest_print.so"; caused by library :libgcc_s.so.1" not found

libtest_print.so에 필요한 libgcc_s.so.1라이브러리가 없다는거같습니다...

이 문제를 해결하려고하는데 잘안되네요...

저보다 먼저 겪으신 분들의 도움을 청하고자 제가 진행한 내용을 설명드리겠습니다.

===============================================================

일단 개발툴은 이클립스를 이용하여 개발하고 있으며

ndk-build는 윈도우에서 하고 있습니다.

프로젝트명은 com.example.projecttest라고 하겠습니다.

다음과 같은 소스 구조로 이루어져 있으며 jni폴더에 각종 .c파일과 Android.mk파일이 있으며 현재 하고자하는 것은 test.c에 있습니다. libtest_print.so파일은 리눅스OS에서 미리 만들어진 so동적라이브러리이며 jni/lib폴더를 만들어 추가해 주었습니다.

jni/lib폴더안에 print.h라는 헤더파일은 libtest_print.so파일에서 만들어진 함수를 쓰기위해 정의해놓았습니다.

이미지

여기까지가 jni폴더 구조에 대한 설명이었으며

Android.mk파일에 대해서 설명드리겠습니다.

jni폴더의 Android.mk 파일입니다.

이미지

LOCAL_SHARED_LIBRARIES로 PREBUILT할 모듈명을 적어주었으며

LOCAL_LDLIBS 에서 -L$(LOCAL_PATH)/lib/ -ltest_print라고 해주었습니다. 이것을 안해주니깐 ndk-build가 안되어서 추가해주었습니다.

아래는 jni/lib/Android.mk 파일입니다.

이미지

PREBUILT_SHARED_LIBRARY 를 통하여 미리 만들어진 libtest_print.so파일을 사용하도록 하였으며

LOCAL_EXPORT_C_INCLUDES를 통하여 print.h의 선언되어진 함수를 사용할수있도록 해주었습니다.

이렇게 만들어준 후 ndk-build를 하면 에러없이 빌드가 되며 libGlobal_Jni.so파일을 libs폴더에 armeabi-v7a에 만들어집니다.

그리고 어플 실행 시 mainactivity에 다음과 같이 로드를 해주었습니다.

이미지

이렇게 해주고 프로그램 실행을 하게 되면 처음 말씀드린 에러가 발생하게 됩니다...

===============================================================

jni/lib폴더를 만들어주기 전에는 잘 사용한 jni이며 외부에서 만들어진 so파일을 사용하고자 하니 문제가 발생고 있습니다....

혹시 제가 잘못한 부분이 있거나 다른 방안 혹은 해결방법이 있으시면 답변달아 주시면 고맙겠습니다.

이외에 추가 내용 질문인데 위의 내용과는 조금 다른내용입니다.

리눅스에서 elf파일(동적라이브러리참조)을 안드로이드 타겟보드에서 사용하는 툴체인(크로스컴파일러(arm-linux-gnueabi)를 이용하여 컴파일 후 adb push를 이용하여 실행파일을 타겟보드에 넣어주고 해당 파일을 실행시키면 no such file or directory라는 문구가 발생하게 되는데

리눅스에서 만들어진 elf파일을 안드로이드에 적용할 수 있는지도 궁금합니다...

이게 안되서 jni를 이용한거거든요...

  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 안드로이드도 리눅스 기반입니다.

    elf 라는 것은 파일 포맷입니다.

    윈도우의 바이너리 같은 경우 pe format 을 사용하며 리눅스는 elf 포맷을 사용하여 바이너리를 생성합니다.

    리눅스에서 만들어진 so 파일을 안드로이드 장비로 옮겨서 디펜던시 체크해서 문제 없으면 될 확률이 큽니다.

    우선 jni 을 이용하여 네이티브 라이브러리를 잘 사용하려면 시스템적인 이해가 필요합니다.

    리눅스 기준으로 so 파일이라는 것은 shared object 약자로 윈도우에서의 dll 과 같은 용도의 공유 라이브러리입니다.

    이 라이브러리들은 또 내부에서 다른 라이브러리를 참조하기 때문에 제대로 사용하려면 참조하고 있는 라이브러리도 모두 존재해야 합니다.

    우선 안드로이드가 설치된 장비에서 ldd 로 사용하고자 하는 라이브러리를 체크해보시기 바랍니다.

    ldd 사용방법입니다.

    https://www.joinc.co.kr/w/man/1/ldd

    아 그리고 노파심에서 적는건데....안드로이드는 보통 arm 프로세서를 사용합니다. 외부에서 만들었다는 so 파일도 arm 기반 리눅스에서 컴파일한거겠죠?

    • 네 외부에서 만들어진 so파일도 arm-linux-gnueabi 컴파일러를 이용하여 크로스컴파일하였습니다 알 수 없는 사용자 2018.4.27 09:49

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)