I am working on a Android APP project with JNI. I have some source of the project, but i only have .so file and the .java file of the source. How can i use the JNI function without the C++ source file?
If you have the Java class that interfaces this .so, you don't need C++ sources to use it. You can even change the native methods from protected to public, if you need, or add in Java wrapper methods that can make using the native methods easier.
Speaking of Android, make sure that your .so file matches the platform (e.g. you cannot use an x86 library on ARM devices). Your .so must have been compiled with a compatible toolchain (e.g. you cannot use Linux compiler). And if your .so was built for certain platform, it may fail to load on older devices: NDK platforms are compatible forward, not backwards.
Related
I have a dynamic linked library (.so) built for general Linux platforms usage (x86, armv7a), now I'm going to port the library for Android usage.
What I expect is to use dlopen in the JNI library's CPP code to access the other library which is not in JNI form. So that I only need to develop a few JNI functions to bridge the exported functions of the original library.
This is all for avoid rebuilding whole codes of the original library. There are a large number of source files and the structure is very complicated. Otherwise I have to rewrite the makefile for NDK building for them.
To try this concept, I almost progress to the last step.
First, I put the original library and JNI library together in location /data/data/com.example.myapp/lib in the device's root file system (I use the emulator in Android Studio, the tool will copy .so files in project's lib folder automatically in installation).
The following I use adt to login the android's shell and I issue file command to list the files in the lib directory
generic_x86_arm:/data/data/com.example.myapp/lib # file *
libSmart.so: ELF shared object, 32-bit LSB 386, BuildID=179c89de2ebe921fe1b9be6e78e83148f3781568, stripped
libmain.so: ELF shared object, 32-bit LSB 386, for Android 16, built by NDK r21e (7075529), BuildID=6b395607222185aac9c163dc205b26add1ab55c4, stripped
libSmart.so: The original library I built for general Linux platforms
libmain.so: The JNI library which will called by JAVA of android activity.
I can open libSmart.so by fopen(), but can't open it by dlopen() which it returns NULL.
Is there some constraints to do these? Or is any libraries used in Android (even not directly called by JAVA) must be built with JNI?
I'm trying to integrate this specific library to my Android project, and the library is written in C/C++. I've miraculously gotten ndk-build to give me the needed .so file.
However, looking at it, there's a sample in the project, and they use a mysterious .jar with the API bindings of the .c/c++ files.
How do i either
create this special .jar file that has the API, based on the .so?
OR
directly add a method to the main c++ file and then call it from Java?
I've tried to re-wrap things using JNI, but it definitely doesn't seem to work. i keep getting UnsatisfiedLinkError.
A lot of the documentation online uses jni as the tutorial. i'm happy with just a few links to tutorials on JNA.
JNA provides a stub native library, libjnidispatch.so for a variety of platforms. You can build this library yourself, or extract one of the pre-built binaries from the project's lib/native/<platform>.jar packages.
You include libjnidispatch.so in your Android project the way you would any other JNI library. This is required; you cannot rely on JNA to dynamically unpack and use its native library automatically like on other platforms. The JNA project includes details for doing so (as well as instructions for building libjnidispatch.so yourself).
You then use jna.jar as you would any other Java jar file, and write your own (Java) mappings to match the native library you're trying to access. There's also a jna-min.jar which omits all the native platform libraries that are normally bundled in jna.jar.
Do go to project properties and build paths and remove JNA 4.0 and related classes.
This will work!
I am trying to learn NDK, and I'd like to use external library (libopus). After reading some articles, I got these steps:
git clone https://android.googlesource.com/platform/external/libopus
mv libopus jni
NDK_PROJECT_PATH=. ndk-build
It crated libs/armeabi/libopus.so file. Yay, awesome! ... And now what? How can I use this library? How can I call its functions and methods?
Also, will my app run on non-ARM architectures (x86, MIPS), because armeabi suggests it'll be ARM only.
You can not just use standard Linux libraries. Java/Android uses the Java Native Interface (JNI) which is special C code that builds the bridge between Java part and native part.
It looks like you already have NDK installed. Look into the project samples, e.g. the "hello-jni" project. In this example you can see what JNI C code you have to write and how to access the self written functions from within your Java code.
Regarding the architectures: Yes, an ARM library is for the ARM platform only. If you want to create a cross-platform App you have to compile all native libraries for each supported platform (usually ARM, ARMv7, x86 and MIPS).
I want to use a static library not compiled with NDK within a C++ class that is compiled usinG NDK. How can this be done. So for example I want to use test.lib function where test.lib is some gnu compiled static C++ library (not compiled by using NDK, its third party so no source avail).
Then is it windows static library (which you used to link with windows executables)? If yes then you cannot use it on android because of two things:
1. lib has non-elf file format (elf is used by android)
2. lib is compiled for x86 (amd64) architecture (android devices have arm processor in most cases).
I would like to create a zip file from files located on the sd card, I have managed to do that using java but I think that the result is too slow, so I thought of going native using the android NDK.
My questions are:
Does anyone know any C/C++ library to zip unzip files that will work on android?
How to know if the library will work on android?
Will this make any difference on performance?
With regard to your question "How to know if the library will work on Android" - it depends on the dependencies that the library has. The standard google NDK has very limited C++ support. If it's written in C you're probably OK, but if it's C++ you need to make sure it uses ONLY the following headers/libraries:
libc (C library) headers
libm (math library) headers
JNI interface headers
libz (Zlib compression) headers
liblog (Android logging) header
OpenGL ES 1.1 and OpenGL ES 2.0 (3D graphics libraries) headers
libjnigraphics (Pixel buffer access) header (for Android 2.2 and above).
A Minimal set of headers for C++ support
(From homepage)
If you need full C++ support, you will need to use the Crystax NDK.
Be forewarned - the process of cross compilation is Very. Complicated. If you're not extremely comfortable on the command line and with the ins and outs of C compilation, linking, etc., I would look for an alternative solution.
I personally like 7zip, they are open sourced here. You can try compiling this within your app in Android NDK. gzip is also another good option.
Given how core zip files (apk files, jar files) are to android, I'd be very surprised if the java zip file functions aren't using native implementations of the actual algorithms.
Remember the SD card itself is slow compared to ordinary disks.