Search code examples
javaandroidc++java-native-interfaceunsatisfiedlinkerror

Unsatisfied link error: Android JNI


I'm working on a Android project which uses JNI. After 2 days of debugging, i still get an error: An unsatisfied link error:

Java.lang.UnsatisfiedLinkError: Native method not found: org.opencv.samples.facedetect.Hello.sayHello:()V

There are many people who have had this problem before, so i have read and tried many possible solutions but i still can't get it to work :(

My code:

Hello.java =

public class Hello { 

    public static native void sayHello(); 

    static {
        Log.i("JNI", "Loading hello");
        System.loadLibrary("hello");
    }
} 

Hello_jni.cpp =

#include <jni.h>
#include <Hello_jni.h>
#include <stdio.h>
#include <android/log.h>

#define LOG_TAG "FaceDetection/DetectionBasedTracker"
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))

extern "C"  JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_Hello_sayHello
 (JNIEnv *env, jclass obj)
{
 printf("Hello world!\n");
 LOGD("werkt");
 return;
}

Hello_jni.h =

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_opencv_samples_facedetect_Hello */

#ifndef _Included_org_opencv_samples_facedetect_Hello
#define _Included_org_opencv_samples_facedetect_Hello
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     org_opencv_samples_facedetect_Hello
 * Method:    sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_Hello_sayHello
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

Android.mk = (first part is for other module from openCV. I'm using the facedetection example from openCV as template for my application)

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

#OPENCV_CAMERA_MODULES:=off
#OPENCV_INSTALL_MODULES:=off
#OPENCV_LIB_TYPE:=SHARED
include ../../sdk/native/jni/OpenCV.mk

LOCAL_SRC_FILES  := DetectionBasedTracker_jni.cpp
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_LDLIBS     += -llog -ldl

LOCAL_MODULE     := detection_based_tracker
include $(BUILD_SHARED_LIBRARY)

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := hello
LOCAL_SRC_FILE := org_opencv_samples_facedetect_Hello_jni.cpp
LOCAL_LDLIBS     += -llog 

include $(BUILD_SHARED_LIBRARY)

from my main activity, i call Hello.sayHello() (static). This triggers the error. Tried: - Removing/adding 'Extern "C"' to sayHello() in the cpp file. - Change function from native to not-native

The library seems to load fine, this is the whole error:

I/JNI(21440): Hello.sayHello() called
I/JNI(21440): Loading hello
D/dalvikvm(21440): Trying to load lib /data/data/org.opencv.samples.facedetect/lib/libhello.so 0x4248c960
D/dalvikvm(21440): Added shared lib /data/data/org.opencv.samples.facedetect/lib/libhello.so 0x4248c960
D/dalvikvm(21440): No JNI_OnLoad found in /data/data/org.opencv.samples.facedetect/lib/libhello.so 0x4248c960, skipping init
W/dalvikvm(21440): No implementation found for native Lorg/opencv/samples/facedetect/Hello;.sayHello:()V
D/AndroidRuntime(21440): Shutting down VM
W/dalvikvm(21440): threadid=1: thread exiting with uncaught exception (group=0x41a4e2a0)
E/AndroidRuntime(21440): FATAL EXCEPTION: main
E/AndroidRuntime(21440): java.lang.UnsatisfiedLinkError: Native method not found: org.opencv.samples.facedetect.Hello.sayHello:()V
E/AndroidRuntime(21440):    at     org.opencv.samples.facedetect.Hello.sayHello(Native Method)

If anybody can help me out, you would be a hero! I just can't get it to work...

Thanks in advance :)

Jelmer


Solution

  • It's working now, the problem was the Android.mk file. Thanks Vorren for giving the solution ;) The working make file is:

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    #OPENCV_CAMERA_MODULES:=off
    #OPENCV_INSTALL_MODULES:=off
    #OPENCV_LIB_TYPE:=SHARED
    include ../../sdk/native/jni/OpenCV.mk
    
    LOCAL_SRC_FILES  := DetectionBasedTracker_jni.cpp
    LOCAL_C_INCLUDES += $(LOCAL_PATH)
    LOCAL_LDLIBS     += -llog -ldl
    
    LOCAL_MODULE     := detection_based_tracker
    
    include $(BUILD_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    
    LOCAL_SRC_FILES := Hello_jni.cpp
    LOCAL_C_INCLUDES := $(LOCAL_PATH)
    LOCAL_LDLIBS     += -llog 
    
    LOCAL_MODULE := hello
    
    include $(BUILD_SHARED_LIBRARY)
    

    there were two errors; syntax error LOCAL_SRC_FILE (missing the S), and i called 'my-dir' 2 times in the make file, which is prohibited (found this here: https://groups.google.com/forum/#!topic/android-ndk/Qmr_WQH-uKk)