I’m currently trying to create a .jar from a .dll, in order to use it on Android applications. I’m quite new with this technology, so I’ll tried to be as clear as possible.
I have 3 distinct parts:
A first .dll which is an API, in C++ and developed with Visual studio 2013.
A second .dll that makes the link between my API and Java code (using JNI, so this is my native library), also developed with Visual studio 2013.
And my Java code that loads my native library and that implements native functions from API. I use eclipse IDE for that stuff, because I read somewhere that was the easiest way to create a .jar.
This part works pretty well. I created a main test and I get all the information from the API in Java. But now, I would like to create a .jar file that I can use on Android and here comes the crows...
I tried many ways, from the simple .jar export, to the One-Jar method, but nothing worked. I always have a link error on my android platform (functions are recognized on the .jar, but their implementations are not).
So here is my question, how to create a kind of ‘static library’ in a .jar that I can use on Android?
I hope I was clear enough, don’t hesitate to ask me more details.
Thank you for your help!
EDIT:
I tried with an Android Library project and my problem is always coming from my loadLibrary() function:
public class MyWrapper {
static {
System.loadLibrary("MyWrapper");
}
public static native int getNegative(int p_number);
public static native int getPositive(int p_number);
}
Every things works fine on my library, but when I use it in android application, I always get this error:
01-27 11:31:29.565: E/AndroidRuntime(7089): FATAL EXCEPTION: main
01-27 11:31:29.565: E/AndroidRuntime(7089): Process: com.example.wrappertest, PID: 7089
01-27 11:31:29.565: E/AndroidRuntime(7089): java.lang.UnsatisfiedLinkError: Couldn't load MyWrapper from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.example.wrappertest-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.example.wrappertest-2, /vendor/lib, /system/lib]]]: findLibrary returned null
My library cound’t be created as static library, to keep the link on the .dll?
A .dll file is usually windows specific. If you're wanting to load native code on Android you'll have to look into using the Native Development Kit. The specifics of using the NDK is a bit beyond what can be explained here, but the Android Developer website provides a decent starting point at http://developer.android.com/tools/sdk/ndk/index.html
As for the jar itself, you may want to look into building an Android Library Project instead. This is essentially a means of packaging a jar with some assets (including native libraries) which can be used by an Android Application project.
Compile your librarie with ndk-build
Create an Android Library module
Create a Java class and JNI wrapper
Disable gradle for ndk-build and create Android.mk and Application.mk in the jni folder
Import the .so library and pre build it on the Android.mk
Invoke ndk-build manually and its done
Related
I am sorry maybe this is stupid what I am asking, but I have a question about linking static/shared libraries in android.
I am creating a new C++ Native android studio project. After build, I open the apk file, and inside lib the folder there are placed libraries libnative-lib.so for every ABI. Size of APK is 3.580 KB.
But if I change inside CMakeLists.txt to build the native lib like Static lib, so now I got this:
add_library(native-lib
STATIC
native-lib.cpp)
When APK is built, I can not find the static library (libnative-lib.a). There is no lib folder in the apk. Also, the size is 2.836 KB.
Can someone please explain(or give me link for more info about this) where is the library placed in the STATIC build?
And on run I got error if I link static:
No implementation found for java.lang.String com.example.myapplication.MainActivity.stringFromJNI()
You can't use native static libraries directly in Android apps.
Android user space is basically a Java (or more precisely Dalvik VM).
So all user-facing applications must be written in Java or Kotlin (which both compile to Dalvik bytecode).
Static C/C++ libraries must be link in to a C/C++ executable or dynamic library to be used. They can not be loaded directly by Linux or Android.
Since Android app does not have a C/C++ executable in it, the only way to use a static library with an Android app is to link it with a dynamic library (*.so) that can be loaded via Java Native Interface.
Since JNI uses the system loader to load the library, it can only load dynamic libraries, and of those, only ones that export functions with proper naming conventions so they can be matched to a Java class that will be used to call the native code.
I have looked at Use prebuilt JNI library in Android Studio 3.1 and How to use .so in a second project in Android?. The first is trying to get a library file without headers working and the other seems to be focusing on a specific issue with his build (although there's some useful information there). I'm relatively new to app development and especially to native development on android. I've gotten a build with the JNI library and some c++ code working, but that seems to be just for building from source.
It's probably a simple answer, but I haven't been able to find documentation on this specifically in the android developers documentation. I'm interested in understanding the correct (or most conventional) place to put and way to use a precompiled library (module/lib/*.so and module/include/*.h) in an android project. Would I even need to use JNI or the NDK if the library is built with another build tool? Another project I have has a native library source object (*.so) in ./obj/local, ./libs, and in many other folders related to JNI. I'm guessing it would be somewhere in there, but I'd like to know what is conventional.
For some context, I'm trying to work with the essentia library. I have followed the guide on compiling for Android and have a build with the general hierarchy mentioned above (essentia/lib and essentia/include) that seems to be working.
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 have a requirement to use C++ code developed using QT inside Xamarin.
The process is like (all done on Windows):
1. Configure and create a static library in QT 5.2
2. Add an Android build kit (MinGW 32) and build the static library for armeabi
3. Use the static library to do P/Invoke inside C# in Xamarin
The problem is that Step 2 above produces a .a file. This is a Linux native object file and I am very sure it will run in Android. How do I use it to perform DllImport and do a P/Invoke? Pardon my ignorence here, I have tried to rename the file to .so and it didn't really help.
Let me know if you need any clarification, your suggestion is very much appreciated.
Thanks, Manoj
You are building a static library. These are meant to be included and loaded at compile time for the programs that use them. What you want it to build a library that can be loaded dynamically, which should end in .so (no you can't just rename it).
You likely need a dynamic library in QT too.
I am trying to make a project to read pdf in android phone.
So, I created the normal Android Project and installed the android-ndk-r6-windows.
And I built the 'libmibookreader.so' and set the native functions in my java class.
But after compiling my project I have a serious Error.
Caused by: java.lang.UnsatisfiedLinkError: Library mibookreader not found
Why this error caused?
I really don't know. I referenced the address of "http://flytgr.thoth.kr/blog/697421".
I followed down as the reference document described.
This is because your library was not loaded by the kernel. Are you sure that you placed your library inside the libs/armeabi/ folder of your project?
Check the logcat when you deploy your application, you should see some messages there that your library was loaded.
If you don't you could also try to use System.loadLibrary(libPath); to manually load your library.