1

Well, the situation I have is the following:

I'm working with an special android device that has some functions extra attached to it. My application is working in android ndk and now I want to call some of the functions provided by the manufacturers.

This functions come in two different .so files, from now mylib1 and mylib2. Also, I got the headers from the manufacturers to be able to implement it fully in ndk.

The problem is that neither of them work. I'm trying to link them to my native-lib (main library) but I get two kind of errors for the same way of linking (I think this part is pretty strange)

For mylib1 I have the following error while I'm trying to compile the code:

[armeabi] SharedLibrary : libnative-lib.so
C:/Users/JuanJo/Documents/JorgeVerdeguerGomez/Workspace/PCPA/app/src/main/jni/native-lib.cpp:17: error: undefined reference to 'Lib_Beep()' clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)

In my first approach, I thought that I was just linking it wrong, despite following multiple answers found in this page and even the code from the google guide itself, but then, I tried to use some functions in mylib2.

The strange thing is that this library does compile, and does provide the definitions to the methods in its header (not for the other header, already tried it) but when I try to run the application, it just stops the app when trying to execute: System.loadLibrary("native-lib");

If I comment that line, the application doesn't stop (it doesn't do anything because everything is in that library, but at least it shows the starting screen)

I also seem to be not able to find any log or file that tells me why it stopped.

After the explanation, I will show you my android.mk and hope you can help me:

LOCAL_PATH :=$(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := mylib1
LOCAL_SRC_FILES := libAndroid.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := mylib2
LOCAL_SRC_FILES := libAndroidEmvKernel.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := libnative-lib

LOCAL_SHARED_LIBRARIES= \
    mylib1 \
    mylib2

LOCAL_SRC_FILES := \
    native-lib.cpp \
    restOfCppFiles.cpp

LOCAL_LDLIBS := -llog \
                -landroid
include $(BUILD_SHARED_LIBRARY)

To be honest, I think that probably the .so are someway not compiled properly or anything like this, because I think is strange to have two different reactions for the same procedure of linking and the same type of files.

Feel free to ask for more info if you think you need it.

Seraphid
  • 11
  • 1
  • 1
  • 4
  • To begin, check if `Lib_Beep` is *exported* in the prebuilt mylib1 (libAndroid.so). Use the **nm** tool which is part of NDK toolchain. Also, make sure that you build for the same ABI as the prebuilt libs. – Alex Cohn Sep 15 '17 at 18:46
  • I have already used the nm tool to check that. Respect the build, is armeabi for both program and sources. – Seraphid Sep 18 '17 at 06:35
  • What does `ndk-build V=1` show? How does **mylib1** (libAndroid.so) appear in the link command? – Alex Cohn Sep 18 '17 at 08:22
  • To be honest I use the compiler from android studio, not the command line one. Anyway, I have started to make the loading and the linking at runtime. Has an extra workload but at least it works. I'm using dlopen to load the library and dlsym to load the functions. – Seraphid Sep 18 '17 at 12:45
  • so at least the so files are compiled properly. – Alex Cohn Sep 18 '17 at 14:32
  • BTW, from what you describe, it looks like the `libAndroid.so` is not in `C:/Users/JuanJo/Documents/JorgeVerdeguerGomez/Workspace/PCPA/app/src/main/jni` directory, as your **Android.mk** expects, but rather in `C:/Users/JuanJo/Documents/JorgeVerdeguerGomez/Workspace/PCPA/app/src/main/jniLibs/armeabi`. If you fix **LOCAL_SRC_FILES** to point there (`../jniLibs/armeabi/libAndroid.so` will be good enough), you can hopefully avoid dlsym. – Alex Cohn Sep 18 '17 at 14:38
  • I have already written an interface for the dlsym build. Anyway, I had a copy of the .so in the folder where Android.mk is stored. In fact, if there was nothing the gradle sync would throw an error. Thanks for your help anyway Alex. – Seraphid Sep 22 '17 at 15:54
  • You can check what **cmake** actually tries to link: https://stackoverflow.com/a/43442227/192373 – Alex Cohn Sep 22 '17 at 20:08
  • **Update**: maybe this [discussion](https://stackoverflow.com/questions/11305767/why-shared-library-path-is-hardcoded-in-execuatble) can help. Apparently, you can use the [patchelf](https://www.mankier.com/1/patchelf) to set SONAME for **mylib2**. – Alex Cohn Sep 25 '17 at 11:33
  • Naming your own library libAndroid is just asking for trouble, given that Android already has a libandroid and the case difference doesn't matter to Windows or Darwin. – Dan Albert Sep 27 '17 at 18:28

0 Answers0