Problem: 

11-13 15:08:17.982: E/dalvikvm(6149): dlopen("/data/app-lib/com.kugistory-1/libkugistory.so") failed: dlopen failed: cannot locate symbol "rand" referenced by "libkugistory.so"...

11-13 15:08:17.982: W/dalvikvm(6149): Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lcom/kugistory/NativeImageProcessor;

11-13 15:08:17.982: D/AndroidRuntime(6149): Shutting down VM

11-13 15:08:17.982: W/dalvikvm(6149): threadid=1: thread exiting with uncaught exception (group=0x41b10ba8)

11-13 15:08:17.992: E/AndroidRuntime(6149): FATAL EXCEPTION: main

11-13 15:08:17.992: E/AndroidRuntime(6149): Process: com.kugistory, PID: 6149

11-13 15:08:17.992: E/AndroidRuntime(6149): java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "rand" referenced by "libkugistory.so"...

11-13 15:08:17.992: E/AndroidRuntime(6149): at java.lang.Runtime.loadLibrary(Runtime.java:364)

11-13 15:08:17.992: E/AndroidRuntime(6149): at java.lang.System.loadLibrary(System.java:526)

11-13 15:08:17.992: E/AndroidRuntime(6149): at com.kugistory.NativeImageProcessor.<clinit>(NativeImageProcessor.java:8)


안드로이드 네이티브(native) 라이브러리를 사용하려다가 위와같은 에러가 생겼다.


찾아보니 ndk-r10의 버그인 듯 하다.


다음과 같은 어떤 사람의 말로는 32-bit, 64-bit 빌드 타입과 관련된 문제인 듯 하다.

You need to use the 32-bit NDK (android-ndk32-r10b-darwin-x86_64) if building for 32-bit targets.

In the ARM headers in the 32-bit target NDK, rand() is declared as a static inline function (and as such does not need to exist as a symbol in libc.so on ARM devices).

In the ARM headers in the 64-bit target NDK, rand() is declared as a regular function, but since it does not exist in the libc.so on ARM devices, there is a runtime error.

Ergo, use the 32-bit target NDK when targeting 32-bit platforms. Or tell Google that their shit is broken.



Trials:

이것을 stl static 라이브러리에서 shared 라이브러리 이용으로 바꾸면 된다는 말을 지나가다가 보고는 다음과 같이 시도했으나 실패했다.







Solution:


해결 방법을 찾는것은 매우 힘들었지만, 해결 방법 자체는 간단했다.


다음과 같이 Application.mk에서 대상 OS들을 몇가지 더 추가하자 거짓말처럼 문제가 풀렸다.


APP_STL := gnustl_static

APP_CPPFLAGS := -frtti -fexceptions

APP_ABI := armeabi armeabi-v7a x86 mips # arm64-v8a x86_64 mips64

APP_PLATFORM := android-16

APP_OPTIM := release

NDK_TOOLCHAIN_VERSION := 4.8



참고로 Android.mk는 다음과 같이 설정해둔 상태였다.

OpenCV를 위한 설정 등 없어도 되는 줄들도 포함되어 있다.

LOCAL_PATH := $(call my-dir)


include $(CLEAR_VARS)


OPENCV_INSTALL_MODULES:= on

OPENCV_CAMERA_MODULES:= off

OPENCV_LIB_TYPE:= STATIC


include E:\OpenCV-2.4.9-android-sdk\sdk\native\jni\OpenCV.mk


LOCAL_MODULE    := Kugistory


FILE_LIST := $(wildcard $(LOCAL_PATH)/*.cpp)

LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%) 

LOCAL_C_INCLUDES += $(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.6/include

LOCAL_C_INCLUDES += $(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include

LOCAL_C_INCLUDES += $(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a-hard/include

LOCAL_LDLIBS += $(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/libgnustl_static.a

LOCAL_LDLIBS +=  -llog -ldl -lz


include $(BUILD_SHARED_LIBRARY)


Posted by Kugi
,