제가 현재
java에서 jni(libAA.so파일)을 호출하면 jni(libAA.so파일)에서
다른.so(libBB.so)파일의 함수를 호출해서 사용하려고 합니다.
- 에뮬레이터에서 실행 결과 /data/data/프로젝트명/lib/밑에 빌드된 라이브러리(.so)파일은 확인해습니다.
- apk 파일내부 확인 결과 apk파일명/lib/armeabi/밑에도 빌드된 라이브러리(.so)파일이 있습니다.(파일사이즈는 다르더군요)
질문 1. 안드로이드에서 위와 같이 jni(libAA.so파일)을 통해서 다른.so(libBB.so)파일의 함수 호출이 안되는 건가요?
질문 2. 된다면, 어떻게 해야 하나요(호출방법이나 라이브러리 링크방법)?
질문 3. 에뮬레이터 내부에 들어가 있는 라이브러리(.so) 파일중 어떤경로의 파일이 쓰이게 되나요?
질문 4. 라이브러리의 파일경로는 어떻게 인식되는지 알고 싶습니다.
(예 : fopen("/파일경로/libBB.so", "a+B"); )
라이브러리 빌드는 제대로 된것 같은데 아래와 같은 에러가 발생합니다.
=========================================
02-28 09:17:25.711: E/AndroidRuntime(284): Caused by: java.lang.UnsatisfiedLinkError: Library AA not found
02-28 09:17:25.711: E/AndroidRuntime(284): at java.lang.Runtime.loadLibrary(Runtime.java:461)
02-28 09:17:25.711: E/AndroidRuntime(284): at java.lang.System.loadLibrary(System.java:557)
02-28 09:17:25.711: E/AndroidRuntime(284): at com.rop.m.crypto.FCOK.<clinit>(FCOK.java:15)
02-28 09:17:25.711: E/AndroidRuntime(284): ... 14 more
=========================================
Andriod.mk
=========================================
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/src/include
LOCAL_CFLAGS += -fomit-frame-pointer -D_REENTRANT -DPTHREADS
LOCAL_SRC_FILES := BBtest.c
LOCAL_LDLIBS += -ldl
LOCAL_MODULE:= BB
include $(BUILD_SHARED_LIBRARY)
...
...
# libAA 빌드
LOCAL_SRC_FILES := AAtest.c
LOCAL_LDLIBS := -llog
LOCAL_SHARED_LIBRARIES := libBB
LOCAL_MODULE := AA
include $(BUILD_SHARED_LIBRARY)
=========================================
우선 답변달아 주신 분들꼐 감사합니다.
답변 감사합니다.
그런데 static library를 사용할 수 없는 상황이어서 꼭 dynamic libarary를 사용해야 하거든요.
다른 방법은 없을까요?
Dynamic Library를 복수로 사용하는 것도 가능합니다.
다만 안드로이드에서는 Dynamic Library를 Java코드에서 명시적으로 모두 불러오셔야 합니다.
System.loadLibrary("AA");
System.loadLibrary("BB");
Java가 BB를 부르고, BB가 AA를 부르기 때문에 BB만 불러도 되지만,
안드로이드에서는 Java가 AA도 불러야만 문제가 없더군요... ㅡ.ㅡ;;;;
답변 감사합니다.
java코드에서 명시적으로 불러도 안되네요 -.-;;
혹시 위의 샘플내용(Android.mk)에서 틀린 부분이 있나요?
혹시 샘플이 있으시다면 ....
System.loadLibrary("AA");
System.loadLibrary("BB");
를
System.loadLibrary("BB");
System.loadLibrary("AA");
해보세요..
UnsatisfiedLinkError <-- 이거땜에 저도 삽질 많이 했는데요 .. so파일 못읽을 때 나옵니다.
so파일 읽기 성공하면 자바에서 선언한 native 메소드명(Java_어쩌고_패키지명 등등 맞나) <- 대소문자 틀리면 함수명으로 오류..
그니까 ...
native메소드를 선언한 자바파일을 javah로 돌려서 헤더파일을 만들어 보면
native 메소드가 C코드 형태로 헤더파일이 생서되는데..
물론 헤더파일이니 함수 선언만 되어있겠지요 ...
그 함수명이 자동으로 자바파일의 패키지명과 짬뽕되어 생성되는데...
이거 대소문자 틀리면 에러나니까 그대로 복사해서 xxx.c 파일 ( 구현부) 만들어놓고 아까 그 메소드 선언부 부분
붙여넣기해서 구현해놓고....
빌드 .... <--- 윈도에서도 빌드 되긴하는데 so파일 넣고 돌리면 UnsatisfiedLinkError 이거 또 나옵니다.. 시그윈에서 빌드하세요
native 메소드를 선언한 자바파일 클래스가 여러개 있는 경우 <-- 각 클래스별로 javah로 헤더파일 따로 만들어서
xxx.c 구현부에 필요한 헤더 import 시키세요 ... 지저분하지만 import 할때 <헤더파일.h> 이러면 안되고 "헤더파일.h" 하세요 ;;
build는 src폴더에서 하는게 편하고 ....
또 음 ....
별짓 다 해도 안되면 C로 HelloWorld 짜고 처음부터 다시 .....
ndk 폴더에 sample폴더보면 예제 몇개 있네요..




둘 중의 하나는 static library로 만들어야 합니다. ndk에 다음과 같은 sample이 있으니 참고해 보세요
LOCAL_PATH:= $(call my-dir)