안드로이드 개발 질문/답변
(글 수 45,052)
안녕하십니까? 안드로이드쪽 관련해서 기존 모듈을 안드로이드쪽에 맞게끔 만들어주고 있습니다.
java에서 jni를 통해 .c로 된 .so파일을 콜하고 해당 .so에서 실제 모듈(.so)로 콜하게 되는데요.
java => jni => A.so <=> B.so(모듈)
A.so는 jni에 맞게끔 jstirng처리된 .c파일입니다. (java와 실제 모듈 B.so를 연결만 시켜주는 역활이죠.)
일단은 리눅스쪽에서 .c 파일을 하나 만들어서(exe) 에서 B.so를 콜해서 정상적으로 되는것까지는 확인했는데요.
jni의 A.so에서 B.so를 콜하려니 도통 안되는군요.
dlopen으로 해서 B.so를 콜했는데요.
아래의 내용은 A.so의 B.so(libsample.so)를 dlopen으로 로딩해오는 부분입니다.
handle = dlopen("/data/data/com.sample.samplejni/lib/libsample.so", RTLD_NOW);
if (!handle)
{
LOGD("open error\n");
LOGD("dlopen error => %s%s\n", dlerror(), stderr);
exit(1);
}
에서 에러가 나네요.
04-28 06:32:16.775: DEBUG/sample-jni_log(1974): dlopen error => Cannot load library: get_lib_extents[706]: 30 - /data/data/com.sample.samplejni/lib/libsample.so is not a valid ELF object
위의 에러가 나네요. /system/lib쪽으로는 들어가질않구요. 파일사이즈가 100kb정도가 돼나서요. read file만되는걸 권한바꾸고
해도 영역이 작아서 들어가질 않아서 /data/data/프로젝트/lib쪽에 넣어주고 그걸
dlopen으로 가져오겠금 하는데 안되네요.
libsample.so 의 선언 sample.h의 선언은..
int test_func(char *input, char *output, char *flag1, char *flag2);
입니다. .c쪽에도 위와 같이 선언되어있구요.
혹 제가 뭘 잘못하는게 있을까요.. 여러분들의 조언 좀 부탁드리겠습니다.
java에서 jni를 통해 .c로 된 .so파일을 콜하고 해당 .so에서 실제 모듈(.so)로 콜하게 되는데요.
java => jni => A.so <=> B.so(모듈)
A.so는 jni에 맞게끔 jstirng처리된 .c파일입니다. (java와 실제 모듈 B.so를 연결만 시켜주는 역활이죠.)
일단은 리눅스쪽에서 .c 파일을 하나 만들어서(exe) 에서 B.so를 콜해서 정상적으로 되는것까지는 확인했는데요.
jni의 A.so에서 B.so를 콜하려니 도통 안되는군요.
dlopen으로 해서 B.so를 콜했는데요.
아래의 내용은 A.so의 B.so(libsample.so)를 dlopen으로 로딩해오는 부분입니다.
handle = dlopen("/data/data/com.sample.samplejni/lib/libsample.so", RTLD_NOW);
if (!handle)
{
LOGD("open error\n");
LOGD("dlopen error => %s%s\n", dlerror(), stderr);
exit(1);
}
에서 에러가 나네요.
04-28 06:32:16.775: DEBUG/sample-jni_log(1974): dlopen error => Cannot load library: get_lib_extents[706]: 30 - /data/data/com.sample.samplejni/lib/libsample.so is not a valid ELF object
위의 에러가 나네요. /system/lib쪽으로는 들어가질않구요. 파일사이즈가 100kb정도가 돼나서요. read file만되는걸 권한바꾸고
해도 영역이 작아서 들어가질 않아서 /data/data/프로젝트/lib쪽에 넣어주고 그걸
dlopen으로 가져오겠금 하는데 안되네요.
libsample.so 의 선언 sample.h의 선언은..
int test_func(char *input, char *output, char *flag1, char *flag2);
입니다. .c쪽에도 위와 같이 선언되어있구요.
혹 제가 뭘 잘못하는게 있을까요.. 여러분들의 조언 좀 부탁드리겠습니다.
2010.04.28 17:04:38
B.so 역시 ndk를 이용해 안드로이드에 맞게 컴파일 해줄 필요가 있습니다. 안드로이드가 리눅스 기반이라고 하지만 사실상 어플리케이션 레벨에서 보면 전혀 별개의 플랫폼이라 보는게 맞습니다.. 또한 리눅스에서 테스트 하셨다는것은 아마 리눅스 pc에서 하신듯한데, 우선 cpu 부터 pc는 x86기반이고 안드로이드는 arm 기반입니다..
2010.04.28 18:03:57
한분이 덧글 달아주셨네요. 아아.. 참고적으로 컴파일 환경을 얘기드리지않은거 같은데요.
cygwin에서 컴파일했습니다. jni .c도 cygwin에서 컴파일을 해주는데요. jni c도 그곳에서 컴파일 후 .so로 만들어주고
하거든요. 이클립스에서 안드로이드쪽 에뮬레이터로 올라갈때 안드로이드에 맞게끔 다시 컴파일 되는걸까요?
움.. 그렇담 안드로이드쪽에 맞게끔 컴파일해줘야한다는 얘기네요..
그렇담 Android.mk에 해당 B.so를 추가해서 그거에 해당되는 .o들을 다 등록해서 자동으로 안드로이드쪽에서 컴파일되고 난후
올라가도록 해야겠네요.
음 제 pc에 cygwin을 설치해서 (windows기반) 했는데.. exe로 B.so를 로딩해서 정상사용했다는것도 cygwin에서..
음.. 그럼 Android.mk에 등록해줘서 컴파일하고 올리는방법으로 해봐야겠네요.
아 근데 .so만들어서 안드로이드쪽에 직접 올려서 콜할수는 없는가보죠.. 안드로이드쪽 컴파일을 이용해서 컴파일해 주고 올려야된다는
것 같은데요... 일단 맨땅에 헤딩 또 시작.. ㅎㅎㅎ.. 답변 감사드립니다.
cygwin에서 컴파일했습니다. jni .c도 cygwin에서 컴파일을 해주는데요. jni c도 그곳에서 컴파일 후 .so로 만들어주고
하거든요. 이클립스에서 안드로이드쪽 에뮬레이터로 올라갈때 안드로이드에 맞게끔 다시 컴파일 되는걸까요?
움.. 그렇담 안드로이드쪽에 맞게끔 컴파일해줘야한다는 얘기네요..
그렇담 Android.mk에 해당 B.so를 추가해서 그거에 해당되는 .o들을 다 등록해서 자동으로 안드로이드쪽에서 컴파일되고 난후
올라가도록 해야겠네요.
음 제 pc에 cygwin을 설치해서 (windows기반) 했는데.. exe로 B.so를 로딩해서 정상사용했다는것도 cygwin에서..
음.. 그럼 Android.mk에 등록해줘서 컴파일하고 올리는방법으로 해봐야겠네요.
아 근데 .so만들어서 안드로이드쪽에 직접 올려서 콜할수는 없는가보죠.. 안드로이드쪽 컴파일을 이용해서 컴파일해 주고 올려야된다는
것 같은데요... 일단 맨땅에 헤딩 또 시작.. ㅎㅎㅎ.. 답변 감사드립니다.