I have recently started working with NDK and am stuck with a problem. I basically want to use an external static library (.so) into my application. Here's what I've tried till now.
Create a library
1) Add a method in the Java class with native keyword
public native static void FibNR ();
2) In the terminal navigate to the project folder and run the following command
mkdir jni
javah -jni -classpath bin/classes/ -d jni/ com.example.fibonaccinative.FibLib
3) Refresh project and add a C file corresponding to the generated H file.
4) Create a Android.mk file in the JNI folder and add the following code in it
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_LIB_TYPE :=STATIC
LOCAL_SRC_FILES := com_example_fibonaccinative_FibLib.c
LOCAL_MODULE := com_example_fibonaccinative_FibLib
include $(BUILD_SHARED_LIBRARY)
5) Build the code using the following command
/Developer/android-ndk-r9b/ndk-build all
The above steps execute successfully and I'm able to view the results of the c code also. Now I want to create a new application and use the generated .so file (com_example_fibonaccinative_FibLib.so) into it. For this I do the following
Use the library
follow steps 1, 2 and 3 from above for the new application
4) Create a Android.mk file in the JNI folder and add the following code in it
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_LIB_TYPE :=STATIC
LOCAL_SRC_FILES := com_example_usingstaticlibrary_LibraryTest.c
LOCAL_MODULE := com_example_usingstaticlibrary_LibraryTest
LOCAL_SHARED_LIBRARIES :=libcom_example_fibonaccinative_FibLib.so
LOCAL_LDLIBS := -L$(SYSROOT)/usr -llog
include $(BUILD_SHARED_LIBRARY)
5) Build the code using the following command
/Developer/android-ndk-r9b/ndk-build all
I'm not sure what to do next. What I think is I need to call the function of the library into com_example_usingstaticlibrary_LibraryTest.c. But doing so gives me an error saying
'com_example_fibonaccinative_FibLib' undeclared
EDIT 1:
1) In project 2 (where I want to use the Prebuilt Shared Library (.so)) I copied the library into the 'jni' folder
2) Changed the Android.mk file with the below text.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libcom_example_fibonaccinative_FibLib
LOCAL_SRC_FILES := libcom_example_fibonaccinative_FibLib.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := com_example_usingstaticlibrary_LibraryTest
LOCAL_SHARED_LIBRARIES := libcom_example_fibonaccinative_FibLib
LOCAL_SRC_FILES := com_example_usingstaticlibrary_LibraryTest.c
include $(BUILD_SHARED_LIBRARY)
3) Added the .h file from the old project (com_example_fibonaccinative_FibLib.h) into the 'jni' folder
4) Changed the source of com_example_usingstaticlibrary_LibraryTest.c to
#include "com_example_usingstaticlibrary_LibraryTest.h"
#include "com_example_fibonaccinative_FibLib.h"
JNIEXPORT jlong JNICALL Java_com_example_usingstaticlibrary_LibraryTest_callLibraryFunction
(JNIEnv *env, jclass class) {
Java_com_example_fibonaccinative_FibLib_fibNR(env, class, 500l);
return -500l;
}
Clean/Build results into the following error
undefined reference to 'Java_com_example_fibonaccinative_FibLib_fibNR'
Edit 2:
With reference to this I've edited the Android.mk as follows
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := com_example_fibonaccinative_FibLib
LOCAL_SRC_FILES := libcom_example_fibonaccinative_FibLib.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := com_example_usingstaticlibrary_LibraryTest
LOCAL_SRC_FILES := com_example_usingstaticlibrary_LibraryTest.c
LOCAL_SHARED_LIBRARIES := com_example_fibonaccinative_FibLib
include $(BUILD_SHARED_LIBRARY)
The NDK build command compiles the code without error. When trying to load the library it gives the following error
Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lcom/example/usingstaticlibrary/LibraryTest
When I remove LOCAL_SHARED_LIBRARIES := com_example_fibonaccinative_FibLib
it works fine but I cannot use any function of the Prebuilt shared library.
Edit 3:
I tried a few more things including the suggestion by @jcm but nothing worked. I'm now attaching the source code. It has both the projects (Cleaned version to reduce size).
- FibonacciNative: Contains the first project.
- UsingStaticLibrary: Contains the second project. I intend to use the Prebuilt Shared Library of the first project into the second one.