0

I am developing an android app where I have to use a shared library (cross-compiled on linux system using NDK toolchain).

Below are the steps I followed:

  1. I am using the 'hello-libs ndk sample'.
  2. The shared library name is libsum.so, where I have two function definitions:
int sum(int a, int b);
int sub(int a, int b);
  1. I have copied libsum.so file to the android app under path //hello-libs/app/libs/arm64-v8a and called sum(10, 20) in //hello-libs/app/src/main/cpp/hello-libs.cpp file.
  2. Updated the CMakeLists.txt file to add shared library while compiling. Updated CMakeLists.txt file below:
...
...
# configure import libs
set(distribution_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../distribution)
...
...
add_library(lib_sum SHARED IMPORTED)
set_target_properties(lib_sum PROPERTIES IMPORTED_LOCATION
    ${distribution_DIR}/sum/lib/${ANDROID_ABI}/libsum.so)

# build application's shared lib
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")

add_library(hello-libs SHARED
            hello-libs.cpp)

target_include_directories(hello-libs PRIVATE
                           ${distribution_DIR}/gmath/include
                           ${distribution_DIR}/gperf/include
                           ${distribution_DIR}/sum/include)

target_link_libraries(hello-libs
                      android
                      lib_gmath
                      lib_gperf
                      lib_sum
                      log)

main.h

#include <stdio.h>

int sum(int a, int b); 
int sub(int a, int b);

But I am getting the below error:

ld: error: undefined symbol: sum(int, int)

Can somebody please help me?

  • How did you update the `CMakeLists.txt` file? How do you link with the library? – Some programmer dude Oct 12 '21 at 16:16
  • Updated the post with the changes in `CMakeLists.txt`. – Sunny Gupta Oct 12 '21 at 16:25
  • Please run `nm -D libsum.so`. Which symbols does it export? Also, please show the header file that you're including in hello-libs.cpp (the one containing the declarations of `sum` and `sub`). – Michael Oct 12 '21 at 16:35
  • Output of `num -D libsum.so` is below: `0000000000002000 A __bss_end__` `0000000000002000 A _bss_end__` `0000000000002000 A __bss_start` `0000000000002000 A __bss_start__` ` U __cxa_atexit` ` U __cxa_finalize` `0000000000002000 A _edata` `0000000000002000 A _end` `0000000000002000 A __end__` `0000000000000650 T main` ` U printf` ` U __register_atfork` `00000000000005fc T sub` `00000000000005a8 T sum` Updated the post with header file. – Sunny Gupta Oct 12 '21 at 16:45
  • Ok, so your `libsum` is written in C, not C++? Since `hello-libs` is written in C++ you might need to edit `main.h` a bit so that the linker will look for unmangled symbol names in `libsum`. See e.g. https://stackoverflow.com/questions/3789340/combining-c-and-c-how-does-ifdef-cplusplus-work – Michael Oct 12 '21 at 17:06
  • Thanks for the input. I have updated the main.h file as per the link shared above. Now, the app is building but failing at runtime. The error is defined below: ` E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.hellolibs, PID: 10035 java.lang.UnsatisfiedLinkError: dlopen failed: library hello-libs/app/src/main/cpp/../../../../distribution/sum/lib/arm64-v8a/libsum.so" not found: needed by /data/app/~~PD60oCgkuKRbLUiB-Rj5Ig==/com.example.hellolibs-WFpgY4kNXeJmCEaiaFQrkg==/lib/arm64/libhello-libs.so in namespace classloader-namespace ` – Sunny Gupta Oct 12 '21 at 17:23

1 Answers1

0

If not already done, you might want to add the visibility flag to the functions by using the JNIEXPORT macro, which expands to attribute((visibility("default"))):

extern "C" { JNIEXPORT jint JNICALL Java_com_example_MyActivity_sum(JNIEnv * env, jobject thisObject, jint a, jint b) { return a + b; } } // extern C

tm243
  • 109
  • 2