마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

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

0 추천

안녕하세요

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

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

 

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

 

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

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를 이용한거거든요...

 

주하린 (170 포인트) 님이 2018년 4월 26일 질문
주하린님이 2018년 4월 26일 수정

1개의 답변

0 추천

리눅스 os에서 빌드한 libtest_print.so를 빌드 할 때   libgcc_s.so.1 를 참조한 것으로 생각되며,

리눅스 pc에서 이 라이브러리를 복사 해 넣어 주어, 찾게 하면 좋겠지만.. 

애시당초 리눅스 os용 라이브러리가 x86 어셈블리로  컴파일 된 라이브러리이기 때문에, 

arm-eabi 어셈블리로 동작되는 폰에서는 동작 시킬 수 없습니다.(x86 폰의 경우 arm을 애뮬레이팅 하긴 합니다.-ㅇ-;)

libtest_print.so 를 디컴파일 해서 arm으로 재 컴파일 하는게 방법일듯 한데.. 간단하진 않을 듯 합니다.

익명사용자 님이 2018년 4월 26일 답변
안드로이드도 리눅스 커널기반으로 알고 있는데
리눅스에서 빌드된 파일을 모듈형태로 안드로이드에 적용시킬수는 없을까요?
비유를 들어 설명 드리면 한국어(C)로 된 문서를 중국어(x86 어셈블리어)로 번역한 걸 가지고, 영어(arm 어셈블리어로 동작하는 기기)에서 사용하려 하니 무슨 말인지 몰라 동작 안될 수 밖에 없습니다.

중국어를 영어로 번역 해 주던지, 중국어를 기기에서 지원 해 줘야만 하는데,
 대부분의 기기는 영어만 할 수 있다보니,
 중국어를 -> 한국어로 변경(디컴파일)  한 후 한국어를 영어로 변경(재컴파일) 하는게 방법이라고 말씀드린 겁니다.

인텔 아톰 칩을 사용하는 x86 용 안드로이드 기기의 경우 중국어(x86 어셈블리어)도 지원하면서 영어(arm 어셈블리어)도  어느정도 지원(대부분 단말이 arm으로 되어 있어서 x86단말에서 arm 명령어를 원어민 수준은 안되도, 어느정도는 지원합니다.) 하기 때문에, 이러한 단말에서 돌릴 경우 동작 될 수도 있습니다.

역으로  arm용 리눅스 커널을 사용하는 PC도 있으니, 이런 PC 에 있는 라이브러리를 구해서 돌린다면, arm 어셈블리어를 사용하는 대부분의 안드로이드 단말에서 돌 가능성이 있구요..

단지 이건 가능성일 뿐 언어가 맞더라도, 제주도어와 표준어 사이의 간격과 같이 PC용 커널과 안드로이드 커널에서 다른 부분이 있다보니, 말이 통해 동작 할 수도 있고, 잘 못 알아들어, SIGABT 같이 엉뚱한 메모리에서 죽을 가능성도 있습니다.
가장 좋은건 C 파일을 구해 NDK 로 컴파일 하는것이고,  해당 명령어를  꼭 단말에서 돌릴 필요가 없다면, 서버 연동 같은 것을 통해 별도의 디바이스에서  처리 해서 내려주는 것도 방법입니다.
생각할 수 있게 답변해주셔서 고맙습니다.

제가 이해한것으로는 리눅스 OS에서 작성된 C파일(한국어) 를 중국어(x86 어셈블리어)로 번역한걸 영어(arm어셈블리어)로 사용하려니 안되는건 알겠습니다.. 번역도 이상할 뿐더러 해석조차 못하니깐요...

그래서 접근한 방법이 c파일(한국어)를 중국어로 번역하는 부분에서 영어(arm어셈블리어로 동작하는 기기)에서 알기위해 BSP에서 제공하는 툴체인(크로스컴파일러)를 이용하여 영어(arm어셈블리어)로 번역하도록 하면 되지 않을까? 라는 생각으로 접근을 한건데요

리눅스 OS에서 크로스 컴파일을 하면 어떨까 해서 arm-linux-gnueabi라는 컴파일러를 이용하여 빌드를 해주었습니다. 그렇게 하면 영어(arm어셈블리어로 동작하는기기)에서 알수 있지 않을까해서요...


처음에는 리눅스 OS에서 현재 적용하려고 하는 안드로이드 기기에서 사용하고 있는 컴파일러(arm-eabi-4.6)와 같은걸로 빌드를 해주려고 하였는데 이럴 경우에는 빌드에러가 나더군요(stdio.h파일을 못찾는다고... ps. 기본적으로 helloworld를 출력하고자하는 간단한 프로젝트를 만들었음) 그래서 arm-linux-gnueabi라는 컴파일러로 바꾸어 빌드를 해준건데요

이 과정에서 뭔가 문제가 있는거같습니다...

안드로이드 툴체인(크로스컴파일러)에 리눅스에서 제공하는 라이브러리를 추가 시키면 될거도같긴한데 컴파일러수정하는게 가능한건가 싶기도하고...
...