How to create .a file instead .so from c source using android studio?
If it is possible , then also I want want to know how to load them and pros and cons of using .a file instead .so
Android relies on Java's System.loadLibrary() to load native code. This call uses the dl* family of functions to load a dynamic library (commonly associated with extension .so).
The dynamic library can specify other libraries as its dependencies, which will be loaded in turn.
After opening the library, the JVM probes it for functions with specially crafted names, which are bound to the corresponding Java methods.
By contrast, a .a file is a static library. It is simply an archive of object files (.o) that are meant for consumption by static linking when compilation.
To answer your question: yes, you could alter your CMakeLists.txt to create static libraries, but eventually you will have to link these together into a dynamic .so in order to load it in Android. See for example the bottom part of this answer where a number of prebuilt static libraries are linked together with a single .cpp file to produce a dynamic library.
Related
I have a shared object bundled with my Android app. It is in the lib folder of the APK. On Android 7 I can just do the following to load it:
lib = dlopen("libfoo.so", RTLD_LAZY);
However, this doesn't work on Android 4. On Android 4 I have to do the following instead:
lib = dlopen("/data/data/<my_package_identifier>/lib/libfoo.so", RTLD_LAZY);
So do I always have to specify the path /data/data/<id>/lib when calling dlopen() on Android? I'm a bit worried about hard-coding paths but as I said, just passing the name of the shared object doesn't work on Android 4.
I know that it is probably easier from the Java side using System.loadLibrary() but I don't want to use that either because it doesn't allow me to unload libraries.
I have a java file which loads .so files and prints the result coming from .so file. I don't have a source code for my .so file. Can anyone tell how in the memory structure .so results are loaded and from where this Java class is reading the results generated by .so and printing them out??
If u have any code that is already written in native language and reluctant about changing it but you would want to use native calls in your java codes and not to rewrite entirely everything java. JNI comes in handy. it converts all your platform specific implementations to platform independent. Performance- and platform-sensitive API implementations in the standard library allows all Java applications to access this functionality.
the library files .so are converted in such a manner.
JNIEnv contains all types of conversion from a native data types to the java data types. it also supports suitable implementations for native method calls, signals are also handled by the JVM.
Java being platform independent native processss specific to a hardware and operating system platform are all made platform independent by mapping native data types and method calls to java. JNI performs the above using the library files example .so or .a files
For JNI mapping u can refer the below link
http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html
Your .so have a JNI glue class that binds all your Java native methods (public native void x();) with compiled native code.
I'm assuming it uses JNI, otherwise I have no idea how its working. If it uses JNI, then it actually creates Java objects on the Java heap in the .so, using the JNI libraries. Look for functions marked "native", these functions map directly to functions in the so that are called when th Java code whats to run something in the library.
The Droidfish Android chess game is written in Java. But its underlying chess engine Stockfish is written in C++. At first, I thought there was a JNI layer that connects these two but there isn't. The C++ stockfish executable is launched, and Java and C++ communicates via stream.
You can launch the C++ stockfish and play with this engine in the command line, no graphical interfaces.
In your question, your native .so library is printing something to stdout/stderr and you want to read these outputs in Java?
We have a c++ project on android, which will be built into .a then release the .a to our users.
The problem is, we have many resource files, and these resources' path is necessary because some 3rd-party libs need them.
The limitation on android is: if we want to put a file in Android APK, we must package it in res or assets and it is not single file any more, so how can we organize our resources?
Our plan is to require our users to package our resources in APK's Assets, then we can extract them to other folder, but it's not user-friendly, do you have any better idea?
thanks
C++ android project, it sounds me weird, may be, you would like to say that you have c++ arm crosscompiled static library .a which it is able to load in an Android project.
I guess you want to share a library which uses many resources, and you need the elegant way to distribute.
Try to create a .jar file which it has native functions:
Firstly create your core class exporting functions and define your
public native functions to JNI.
Don't use activities, if you need to access to activity context, pass
through parameters.
If you want to use resources, your layouts will not be able to use in
your parent android project.
You can use drawable files and you can add layout files programatically (with activity context).
If you are going to use some resources such as xml config files, put
in the res/raw folder or in assets folder.
If you have good Java and JNI skills, this task is not so difficult.
Hope the advices help you.
Cheers.
I think you need to develope a NativeActivity. If you follow the proper documentation, you could create a working app to do whatever you want. If you want to open assets, process, you can do it, and launch this app from another one.
If you really want a single library to be used, Just do it in c/cpp, and initialize it with a JNI function call providing the asset path and aassetmanager, and use the AAssetManager object in native. You will need to include jni.h, of course you will need to crosscompile the library using the NDK toolchain, and gradle or cmake toolchain scripts.
I am working on an Android project that has a native ".so" file embedded in an apk. Whenever we need to release a bug fix we are now releasing a new apk file with ".so" which has the fix. But this is a huge file and is not efficient.
So my question is, is it possible to update the ".so" inside the ".apk" with only the relevant ".o" files that have changed? Meaning keeping the rest of the ".so" file the same, can we just update only those ".o" files that changed? Similar to how some systems push their bug fixes.
Updating parts of dynamic library (.so) is not possible. It's not like a static library (.a), which is, essentially, just a plain archive with object files. A dynamic library is more like a usual executable and can be thought of as just a program with no main. In fact, shared libraries are usually compiled as PIC and overall, if one part of the library changes, all other parts should be updated.
Say, there's one more instruction in the code of some function a, which is followed by functions b and c. Then addresses of b and c should be increased by size of the instruction which got added to a. Then all call sites of b and c inside this dynamic library should be updated with new addresses.
That said, it could be done in theory, but the cost of implementation is much higher than profit from it.
Does anyone have any experience using JNI to call native C/C++ libraries in Android? Is the environment suitable for running C/C++ libraries and if so is there anything specific about the environment which you need to accommodate?
Thanks
My understanding is that Android provides only a subset of the standard C++ runtime library. For example, Android does not support exceptions in native code. I think there are other restrictions as well.
One complication is that, while Android itself might include many native libraries, only some of them are considered stable enough to link against. The Android NDK page lists the libraries which are safe.
libc (C library) headers
libm (math library) headers
JNI interface headers
libz (Zlib compression) headers
liblog (Android logging) header
A Minimal set of headers for C++ support
If your C library only uses those, you should be fine. C++ support sounds a little spottier.
For a good example of C and Java integration, check this out:
https://github.com/jackpal/Android-Terminal-Emulator
Untar the files and you can find a jni/termExec.cpp - which uses normal C API like "exec()", "fork()", and "open(/dev/ptmx)" to implement terminal emulation (http://linux.die.net/man/4/ptmx).
Looking up the jni/Android.mk file, and u can see that the cpp is compiled as a library - libandroidterm.
And then the java application (src/jackpal/androidterm/Exec.java) will load the library via System.loadLibrary("androidterm").
I think this application provide a small enough example for u to extend whichever way u like - either the cpp or the java file. (The cpp file is basically C-based, not C plus plus).
And remember the mapping between them, for example here it is:
static JNINativeMethod method_table[]
= {
{ "createSubprocess", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[I)Ljava/io/FileDescriptor;",
(void*) android_os_Exec_createSubProcess },
{ "setPtyWindowSize", "(Ljava/io/FileDescriptor;IIII)V",
(void*) android_os_Exec_setPtyWindowSize},
{ "waitFor", "(I)I",
(void*) android_os_Exec_waitFor},
{ "close", "(Ljava/io/FileDescriptor;)V",
(void*) android_os_Exec_close} };
for a C library, you shouldn't have any trouble. a C++ library might be more fun if it uses much of the standard library, because most of the C++ standard library is missing, but you can always supply your own "mini-STL". that's basically how external/webkit works.
much of Android's java.util.regex, java.nio.charset, java.util, and java.text are implemented by calling ICU4C, for example. (the library's in external/icu4c and the JNI is in dalvik/libcore/icu/src/main/native.) a mix of ICU's C and C++ interfaces are used, so you can rest assured this stuff gets quite a good workout on a daily basis ;-)