2014-02-20 2 views
2

System.loadLibrary("my_shared_lib"); 을 사용하여 원시 라이브러리를로드하는 데 문제가 있습니다.이 호출은 결코 반환되지 않습니다. 내 프로젝트에서System.loadLibrary 호출을 사용하여 공유 라이브러리를로드하지 않습니다.

내가 여러 정적 라이브러리는 NKD-빌드 스크립트를 사용하여 구축이 : 여기

는 상황이다. 를 구축 잘 내가 필요로하는 각 .a LIB이 Android.mk을 사용하여 작동 :

**Android.mk used for static libs** 

LOCAL_PATH:= $(call my-dir) 

include $(CLEAR_VARS) 

LOCAL_MODULE := my_static_lib_1 

# Include paths 
LOCAL_C_INCLUDES := \ 
    $(PATH_TO_INCLUDES1) \ 
    $(PATH_TO_INCLUDES2) 

# Sources 
LOCAL_SRC_FILES := \ 
    my_source_1.cpp\ 
    my_source_11.cpp 


# Target 
include $(BUILD_STATIC_LIBRARY) 

이 정적 라이브러리 (자바 소스에서 호출) 일부 JNI 래퍼와 사이에, 물론 네이티브 (C++) 소스가 포함되어 있습니다.

모든 정적 라이브러리 (.a)를 빌드하고 나면 필요한 모든 .a 라이브러리가 포함 된 공유 라이브러리 (.so)를 만들고 싶습니다. 여기 내가이 공유 라이브러리 구축하기 위해 사용하고있어 Android.mk이다 (I 확인할 수

LOCAL_PATH := $(call my-dir) 
#---------- 
# Static prebuilt libs 
#---------- 
#-- my_static_lib_1 
include $(CLEAR_VARS) 
LOCAL_MODULE := my_static_lib_1 
LOCAL_SRC_FILES := $(PATH_TO_LIBS)/my_static_lib_1.a 
include $(PREBUILT_STATIC_LIBRARY) 

#-- my_static_lib_2 
include $(CLEAR_VARS) 
LOCAL_MODULE := my_static_lib_2 
LOCAL_SRC_FILES := $(PATH_TO_LIBS)/my_static_lib_2.a 
include $(PREBUILT_STATIC_LIBRARY) 

#---------- 
# Building shared lib 
#---------- 
include $(CLEAR_VARS) 
LOCAL_MODULE := my_shared_lib 

#-- Some of the .a static libs need these libs 
LOCAL_LDLIBS := \ 
    -lz\ 
    -llog \ 
    $(PATH_TO_NDK_LIBS)\libstlport_static.a 

#-- This variable is used to force libs to be included in the .so 
LOCAL_WHOLE_STATIC_LIBRARIES := \ 
    my_static_lib_1\ 
    my_static_lib_2 

include $(BUILD_SHARED_LIBRARY) 

이 나에게 완벽한 .so 파일을 빌드 .a libs와의 모든 기능을 포함을 그 생성에 nm 명령을 사용하여 lib). , 내가 MyClass에의 새로운 인스턴스를 만드는거야

,의 loadLibrary가 호출 :

public class MyClass 
{ 
    static { 
     Log.d("MYLOGS", "Loading..."); 
     System.loadLibrary("my_shared_lib"); 
     Log.d("MYLOGS", "Loaded."); 
    } 
    ... 
} 

문제 :

는 완료로, 여기에 .java 파일을 동적으로 .so lib 디렉토리를로드 하지만 결코 돌아 오지 않습니다. Loaded.은 아니지만 Loading... 로그를 볼 수 있습니다. logCat은 Trying to load lib [...].so라고하지만 그게 전부입니다. 앱이 정지합니다.

.so 파일에 하나의 정적 라이브러리 .a 만 있으면이 모든 기능이 정상적으로 작동합니다. 이 경우 내 원시 코드를 완벽하게 호출 할 수 있습니다. 하지만 내 프로젝트 8 .a 파일을 사용하고 loadLibrary 해당 끝나지 않기 때문에 내가 고정 된 응용 있어요.

loadLibrary 통화에 문제가 있습니까? 너는 어떤 생각을 가지고 있니?

감사합니다.

+0

무한 루프에 들어가는 정적 초기화 프로그램이나로드 유형의 함수를 사용할 수 있습니까? "앱이 돌아 오지 않을"때 실제로 실제로 끝나는 것은 무엇입니까? Application Not Responding 대화 상자가 생깁니 까? 다양한 스레드가 멈춘 위치를 나타내는 logcat의 내용은 무엇입니까? 실수로 여러 개의 .a 파일로 빌드 된 간단한 라이브러리로 실제 라이브러리를 대체하고 여러 파일을 포함하고 있는지 또는 특히 파일 중 하나인지 여부를 좁힐 수 있는지 확인하십시오. –

+0

또한 라이브러리 로딩을 지연 시켜서 ndk-gdb를 먼저 연결 한 다음 디버거로로드를 시도하는 동안 일어날 일을 볼 수 있습니다. –

+0

앱이 응답하지 않는다는 대화 상자가 없습니다. 검은 색 화면이 있고 logcat에 "시작 시간 제한이 만료되어 잠자기 잠금을 포기했습니다."라고 표시됩니다. "lib.so를로드하려고 시도한 직후" (loadLibrary가 앱 실행시 호출된다는 것을 알고 있으므로 교착 상태가 아니지만 loadLibrary가 뭔가를 기다리는 것처럼 보입니다 ... – Vincent

답변

3

내 코드에서 무엇이 잘못되었는지 알아 냈습니다.의 loadLibrary가 .so 라이브러리를로드 사실 때

, 그것은 물론 .so에 포함 된 모든 .a lib 디렉토리의 모든 세계를 포함하여 .so에 선언 된 모든 글로벌 변수/상수를 만듭니다.

일부 전역 코드는 생성자를 통해 일부 코드를 실행합니다. 내 .a libs 아키텍처에서이 코드가 너무 일찍 호출 되었기 때문에 어느 시점에 교착 상태에 빠져 있다는 것을 알았습니다 (필요한 일부 항목이 아직 존재하지 않음). 나는 그것이 loadLibrary 시간에 부름을 기대하지 않았습니다.

그렇다면 누구나 도움이 될 수 있습니다. loadLibrary에는로드하려는 .so 라이브러리에 포함 된 모든 전역 개체가 생성됩니다.

내 실수 였는지 알지 못했습니다.

+0

** gcc ** 특정 '__attribute __ ((생성자))' '__init'. 공유 라이브러리를로드 할 때 이들 모두가 어떻게 작동하는지 이해하고 싶다면 [GCC docs] (http://gcc.gnu.org/onlinedocs/gccint/Initialization.html)를 참조하십시오. 그리고'JNI_OnLoad)'라고 부르며 모든 생성자가 완료된 후에 _ 호출됩니다. –

1

일반적으로 공유 라이브러리 (.so)를 빌드 할 때 -fPIC와 같은 일종의 컴파일러 옵션을 사용하여 위치 독립적 코드을 생성합니다. 반면 정적 라이브러리 (.a)를 빌드하면 이러한 옵션이 사용되지 않습니다. 정적 라이브러리를 공유 라이브러리에 패키지해도 정적 라이브러리의 이진 코드는 위치 독립적이지 않습니다. loadLibrary()가 실패하는 이유입니다.

내가 너라면 정적 라이브러리를 공유 라이브러리에 저장하지 않고 대신 -fPIC 또는 이와 동등한 것으로 모든 C++ 파일을 컴파일합니다.

관련 문제