My problem is as follows.
I need to create a library in Java. So far so good.
Like any decent Java Libraries, it must be usable on any JVM.
But the difficulty here is that this library will contain a lot of native code.
I have some knowledge in JNI.
I've tried creating a few native methods in Java in an Android application with Android Studio and with the Android NDK.
That's great I can do a lot of HelloWorld examples. But how can I export this as a library ?
My project needs external C++ Libraries.
I would like to wrap these libraries and use them in a JNI wrapper wrapped inside a Java Library.
See the following schema :
To make things even simpler, take a simple HelloWorld JNI API for example.
Create a Java Desktop App (or anything else). Import the Helloworld JNI API (as jar), call String HelloWorldJNI_API.sayHello(String yourName) and print the result.
What is required here :
The JNI API will obviously declare the sayHello() method as a
native method ;
The argument (String yourName) is sent to JNI ;
The JNI code calls an internal awesome C++ so library that crunches the data and returns a "hello" + "yourName" (awesome, right ?)
The JNI code returns the result as a jstring
Finally, the Java API returns the result as a String
and voila !
This simple example should show you what I am trying to do.
Well, your Library will contain both the .jar file with the java wrapper code as well as the native files (.so if you're on linux based, or .dll if you're on windows).
Here's where the fun begins :
Because native is compiled in processor assembly language you will have to compile the .so for all your supported target (eg for all android with native support since like forever):
armv5, armv7, armv7s , arm64
Now, you will have to provide an archive with all the above.
This is the case where you want a stand alone library, without providing the code to the developer.
If you can provide the code,then you don't need to worry about different architectures.
Related
I wrote a JNI wrapper for .net DLL file (DLL has been updated accordingly) but the solution stucks as soon as the call to dll function is made.
I have a .net dll which is used to access SecuGen Fingerprint scanner. It is working fine when used in a .net project.
Now I want to use it in a JAVA project. I have updated the dll file according to the JNI requirements. It is not returning once the function in a dll has bee called that is the control leaves JVM and hence i cant debug what is wrong or happening.
Edit: I have finally been able to call one of function from dll (a simpler one). But still when i call the CaptureImage it just hangs.
What you are trying to do will not work.
.net DLLs cannot be used directly from Java with JNI. JNI can only load native DLLs.
You need a "bridge" dll, or library, meaning a native dll that loads the .net stuff for you. Then you use that native dll from JNI.
Take a look at this open source project:
JNI4Net: bridge between Java and .NET (intraprocess, fast, object oriented, open-source)
It seems to do what you need.
There seems to be "jni.h" header in the android toolchain but no library to link to.
Can somebody guide me how can I invoke Java functions from C code in my app?
Android does not export a JNI library. This means that there is no way in the system to call JNI_CreateJavaVM() and her ilk from user-space C code. You can create your own JVM, but it will not be the same Java, and won't have access to Android SDK classes and methods.
In Android, a Zigote process is started with a special JVM (Dalvik or ART), and then Java can load your C code (in form of .so files), not vice versa.
Your C code can use the standard JNI techniques like CallVoidMethod() and her kin to invoke Java methods. Note that Android SDK Java methods often need some 'handles', like context, to have their work done; usually, you must rely on some calls from Java to C that will give you these handles.
I just saw the open source project on this in github (googlevr) and my question is how is it possible for C++ work with Java? I can understand that Java is for android stuff and C++ is for graphic, memory and tracking but how does two different compiled language work together?
In C and C++ you can create shared libraries. They are handled a bit differently for each platform, but do roughly the same thing.
Windows creates a .dll
Mac creates a .dylib
Linux creates a .so
These represent executable code that can be called by any process. This means that java code, matlab code, python code, etc can call code written in C/C++. Java uses a feature called JNI (Java Native Interface) to do this. JNI is notoriously tricky to setup and manage, so a lot of people use a library like Swig which essentially manages everything you need related to JNI in order to make calling precompiled C++ code from Java easier.
The key here is "precompiled". Someone, at some point, maybe even you, had to take the source code and compile it into a dll, dylib, or so and you have to have that shared library set up where the code that needs to use it (in this case your java app) can see it so that when the java app starts it can load the shared library and make calls into it.
For java one consideration is that java code is inherently cross-platform. C++ code needs to be compiled against each platform. So when you distribute your java app, you need to make sure you have a shared library available that is accessible for whichever platform it is being run on.
I need to access a list of Wifi devices on Mac OSX from Java code and after researching it, I've found that I need to resort to "native" code - namely the CoreWLAN framework and the CWInterface.h class (https://developer.apple.com/library/mac/#documentation/CoreWLAN/Reference/CWInterface_reference/translated_content/CWInterface.html)
I initially thought I would be able to call this code using JNA but realized that I needed something since CoreWLAN is Objective-C (not C/C++).
I've tried this Objective-C Java bridge (https://github.com/shannah/Java-Objective-C-Bridge) but I can't work out how to make it find the CoreWLAN framework.
So I've also tried using JNAerator (https://code.google.com/p/jnaerator/wiki/ObjectiveC) so I can I use BridJ (https://code.google.com/p/bridj/), but I can't make it generate the right Java code.
Just using this style java -Xmx1000m -jar jnaerator.jar -framework CoreWLAN -jar CoreWlan.jar runs quickly but results in a jar that only contains mappings for CoreWlan.h
If I run jnaerator against CWInterface.h then jnaerator fails.
(I'm using the latest snapshot version of jnaerator)
What is the best way to call methods on CWInterface.h from Java?
What I would do is create a C++ class that communicates with the Java code through JNI. You can use both C++ and Obj-C in your xCode project. I haven't tried myself to use a Obj-C++ class with JNI, but I would just create a C++ class responsible for all communication between Java and Obj-C, this class can just be included in the Obj-C class where you need it (change the extension of this Obj-C file to .mm since it'll include C++ code).
I found this a helpful article on JNI: http://www.ibm.com/developerworks/java/tutorials/j-jni/
Personally I would do this via two totally separate programs that communicate via a shared memory mapped file. One program written in straight Objective-C, and the other in straight Java.
Memory mapping would mean that both programs would have access to the same region of memory, without having to resort to JNI at all.
Notes on memory mapping from Java:
http://javarevisited.blogspot.co.uk/2012/01/memorymapped-file-and-io-in-java.html
Notes on memory mapping from Objective C:
https://gist.github.com/jverkoey/2985830
That said, if you do want to do go the JNI route, then Apple has the following advice:
It is recommended that you use the Java JNI template in Xcode as a starting point for your JNI development.
To interoperate with the Objective-C runtime from JNI, link against JavaNativeFoundation.framework, which
is a sub-framework of JavaVM.framework. It contains Objective-C classes and macros to automatically set up
and tear down autorelease pools, catch and re-throw Java and Cocoa exceptions, hold JNI global references
in Foundation container classes, and convert object graphs of strings, numbers, lists, maps, and sets.
The above quotes were taken from here:
https://developer.apple.com/library/mac/documentation/java/conceptual/java14development/Java14Development.pdf
You can use the java objective-c bridge for this. You just need to load the framework you want to use with jna's Native.loadLibrary() method.
This example uses the WebKit framework. https://github.com/shannah/Java-Objective-C-Bridge/blob/master/java/test/ca/weblite/objc/TestWebView.java
I'm starting to learn java's JNI to use with an android device.
As I read somewhere, you must have some "glue" for the C++ part in order to be loaded through JNI.
My question is: Is it posible to have a run() function in C with the glue for JNI having that running the real app and having java only for the entry point?
Because I don't know if when invoking that run() function through JNI it may cause problems if that function calls another functions and so on.
Thanks for the tip!
EDIT: I want to code in C++ using ndk and trying to avoid coding in java. thus, I wanted to know if a) if I can compile and run in native with ndk or b) if i can use java only to invoke my app, example: calling woth jni something like app->run() and let it do all stuff instead of java. then, java will act only as an entry point.
If you want to develop for Android in C/C++ (no Java) AND you target newer devices (Gingerbread, android-9 app platform onwards) consider using NativeActivity.
See http://developer.android.com/reference/android/app/NativeActivity.html and folder inside NDK package $NDK/docs/NATIVE-ACTIVITY.HTML together with the sample code $NDK/samples/native-activity.
Good luck!
I made a step-by-step howto in the following post: How to create dll using android You can read it and put questions if you don't understand something.