12

I'm trying to create a shared library that links to another shared library.

Here is my main module Android.mk:

TOP_LOCAL_PATH := $(call my-dir)
include $(call all-subdir-makefiles)

LOCAL_PATH := $(TOP_LOCAL_PATH)

include $(CLEAR_VARS)

LOCAL_CPP_EXTENSION := cpp


LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/ $(LOCAL_PATH)/lib/include
LOCAL_MODULE    := SightCore-jni
LOCAL_SRC_FILES := SightDemo.cpp SightCore-jni.cpp
LOCAL_SHARED_LIBRARIES := SightAPI
LOCAL_LDLIBS = -llog 

include $(BUILD_SHARED_LIBRARY)

I also have the prebuilt shared library in ./lib directory with its own Android.mk file:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := SightAPI
LOCAL_SRC_FILES := libSightAPI.so
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include

include $(PREBUILT_SHARED_LIBRARY)

The SightCore-jni.cpp source file is the jni interface to the shared library and is loaded using the command

System.loadLibrary("SightCore-jni");  

During the ndk-build process I get no compilation or linkage errors. When I try to run the application and access one of the native methods I get the UnsatsfiedLinkError. I noticed that if disable the references to the SightAPI in my jni code and put a typo to the LOCAL_STATIC_LIBRARIES := SightAPI line, The build is successful and there is no UnsatisfiedLinkError.
This mean that the jni code I have is good (I'm actually sure it is ok...)

So the observation is as follows:
If I compile the shared library with the prebuilt shared library I get a corrupted .so file.

If I compile the same ndk project without linking to the prebuilt shared library there is no problem loading the shared library from the java side.

Please help me out if you can.

Thanks in advance,

Ita

Ita
  • 1,282
  • 1
  • 15
  • 21
  • What error message do you see in logcat? Should be a message above the UnsatisfiedLinkError exception, likely with output from dlopen(). Also, what version of Android are you using? – fadden Mar 14 '11 at 23:17
  • How can i link my shared library to Android NDK project Can u please Explain me – user1089679 Mar 26 '12 at 08:56

3 Answers3

13

Found the issue.

Apparently the ndk build system doesn't automatically load referenced shared libraries, even if they are declared in your Android.mk.

I had to call on System.loadLibrary(SightAPI) & System.loadLibrary("SightCore-jni") in order to solve this issue. I would have expected that the only library to load would have been the main library SightCore-jni.

Well..I guess the moral is If you want something done, do it yourself :)

+1 to Roy Samuel for his effort and correct instincts.

I hope this helps anyone.

Cheers

Ita
  • 1,282
  • 1
  • 15
  • 21
4
  1. Have you made sure that the cpp function name, that you'd like to use over JNI, is corresponding to the package name of the Java wrapper class where System.loadLibrary("SightCore-jni"); is present?

    e.g. If you would like to use the C function, myFunction in the java layer, and suppose your JNI wrapper class is in the package com.my.package.sightcore, then your C code function name should be like this :

     JNIEXPORT  JNICALL Java_com_my_package_sightcore_myFunction(JNIEnv * env, jobject thiz, ...)
    
  2. If you are running your app on your device, See if the API levels, and hence, the sdk release matches to your device's android version (API level).

Hope this helps. Let me know if you need more clarifications...

Community
  • 1
  • 1
Roy Samuel
  • 790
  • 9
  • 24
  • refer this excellent tutorial, this might help : http://mindtherobot.com/blog/452/android-beginners-ndk-setup-step-by-step/ – Roy Samuel Mar 18 '11 at 04:42
  • what happens if we have a .so file that was firstly not designed to be used in JNI environment. The method of this library would not have the naming convention created by javah command of applying package name and class name to the function. How would this work out? Thank you – Thiago Jun 24 '11 at 17:08
  • As far as I know, if the .so file does not have the correct naming convention, i.e, the JNI naming scheme, it will not be "exported" to the java level. Hence can't be used. You will have to obtain the source to this library, and build it with the correct naming convention, so that it can be visible for use at the Java layer. Hope this helps. – Roy Samuel Jun 28 '11 at 07:00
  • A simple solution if you cannot get the source of the original could be to write a library wrapping the original in functions with names matching the jni convention. – Chris Stratton Jul 02 '12 at 16:58
0

This happened to me, and the solution for me was to make sure I was including the proper file libgnustl_shared.so and not libc++_shared.so after I switched compilers. So, just making sure either one of these files is the correct one for your build, and making sure it's been updated with the latest, you shouldn't get this issue any longer.

Mike Weir
  • 3,094
  • 1
  • 30
  • 46