0

I am writing a wrapper class for C++ ".so". I want to use the library in Java application and Android app using JNI. So I have to create header file and cpp file which will do JNI calls. I could use that on Linux in Java application.

The steps I followed:

  1. Created java class and called native functions in that class

    public class TestWrapper { 
        static {
            System.load("/home/native.so");    
    }         
        public static void main(String[] args) {
            new TestWrapper().TestWrapper();    
    } 
        private native void sayHello();
    }
    
  2. Created header file and cpp file. CCP contains following code

    JNIEXPORT void JNICALL Java_TestWrapper_sayHello(JNIEnv *, jobject){
    uint16_t data = 0;
    void (*func_print_name)(const uint16_t*);   
    void* handle = dlopen("libCppTobeUsed.so.0", RTLD_LAZY);
    if (handle){
        *(void**)(&func_print_name) = dlsym(handle, function_name);    
        func_print_name(&data);
        dlclose(handle);
        std::cout << "data received .." << data << std::endl;
      }
        }
    }
    
  3. Compiled this cpp class and generated "native.so"

This is working fine. The "native.so" could call the fuction form "ibCppTobeUsed.so.0" when called from TestWrapper.java.

I want to use same library for android as well. So, I have to write wrapper class all over again in Android NDK? Or I can compile my "native.so" for Android platform?

If I try to use it directly, I get error

"install_failed_no_matching_abis".

4
  • In what CPU architecture or Application Binary Interface (ABI) is your .so written in? If it was compiled for Linux it could be x86 or x64 which won't run on ARM devices. Commented Jul 3, 2019 at 6:50
  • Compiled for x86. So, I need to rewrite the wrapper class in android NDK? Commented Jul 3, 2019 at 7:01
  • You'll need to recompile the C/C++ code that created the .so with the NDK. The JNI wrapper classes need to be done for all architectures regardless. Commented Jul 3, 2019 at 7:09
  • Ok, got it. Thanks for the direction. Commented Jul 3, 2019 at 7:14

1 Answer 1

2

No, you cannot use the same shared library. Android is not GNU. You need to compile your libraries for Android.

So, I have to write wrapper class all over again in Android NDK?

No, you can write it in a way that works for both. You need to factor our your JNI wrapper class from your main class, since Android uses Activity instead of main.

I would also strongly recommend against ever relying on dlclose on any platform. The API is not sound, and will lead to surprising behavior with modern C++. A single global thread_local with a non-trivial destructor renders the library un-unloadable, so the next dlopen will not reset library state as you might expect. If you need to implement initialization/finalization logic for your library, make explicit Initialize and Finalize functions a part of the libary and call them directly.

Without knowing your architecture's full architecture I can't be sure, but from the sample you've given here I'd recommend dropping the dlopen/dlsym from your JNI entirely and just link against libCppTobeUsed directly.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.