13

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

2
  • 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? Commented Mar 14, 2011 at 23:17
  • How can i link my shared library to Android NDK project Can u please Explain me Commented Mar 26, 2012 at 8:56

3 Answers 3

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

Sign up to request clarification or add additional context in comments.

1 Comment

I have to Put this System.loadLibrary(SightAPI) in static{ }.? and with "SightAPI" ?
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...

4 Comments

refer this excellent tutorial, this might help : mindtherobot.com/blog/452/…
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
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.
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.
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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.