Issue
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:
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(); }
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; } } }
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".
Solution
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.
Answered By - Dan Albert
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.