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.
Related
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.
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.
I have a general question according an android app, I need to use some pcap functionality in my android app. Because java does not give the possibility in raw packet injections and low layer programming (as far as I know, pls correct me if I'm wrong) so I was looking for an alternative. So far I found the following:
ANDROID NDK
JNETPCAP
Any suggestions which one I should use or does anyone have other suggestions?
The JNI Solution
You need to wrap the calls and the logic you need out of libpcap in C or C++ and expose the underlying functions through JNI (Java Native Interface) so your application can call native code in Java.
The documentation on JNI is pretty complete on internet, a lot of tutorials exists on this subject such as this one.
If you want to easily wrap native code in JNI you can use Swig which allow you to automatically generate JNI code based on your C/C++ native headers.
The obtained JNI code should be compiled using the Android NDK as a dynamic library (.so). This library is to be placed in your application package under libs/. You can then invoke System.loadLibrary(path_to_you_dynamic_library) to load all the symbols contained in the library and use them in Java.
Using a third-party library
If you're afraid of getting headaches while figuring out how to use JNI, you can look at this library which does the hard work for you, and provides an API to manipulate raw sockets in Java.
http://www.savarese.com/software/rocksaw/
You need to wrap the calls and the logic you need out of libpcap in C or C++ and expose the underlying functions through JNI (Java Native Interface) so your application can call native code in Java.
Or you need to get a library that's already done that, such as, err, umm, jNetPcap.
One problem you may have with any attempt to do packet capture on Android - or any other OS using the Linux kernel - is that, by default, the underlying kernel mechanism used by libpcap (PF_PACKET sockets) requires root privileges. If there's a way to run your code as root, or to give it CAP_NET_RAW and possibly CAP_NET_ADMIN privileges, it might be possible to make it work.
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.
I want to create native Mac OS X application using Cocoa + Objective C but I need to connect to proprietary data source, and for this, owner of the data source only provides Java library. So I need to somehow import this Java library into my project and call functions on its Java classes.(Or create java wrapper around this library and then call my wrapper from objective-C).
Now, how can I do this? Quick google search leads me to JNI but I haven't found any good and actual(current) article/tutorial. I would really need some HOW TO article, how to load this java library, start VM if needed, and how to create java objects and call functions on them. Really something simple and I can move from there. Thanks.
Just to clarify, I repeat: I WANT to call Java functions from Objective-C, I do NOT want to call native functions from Java.
You're probably looking for the Invocation API, a little-known corner of Java Native Interface (JNI) which allows you to load the Java runtime in-process.
That said, you might have an easier time of it with a Java service application that communicates with your Objective-C application over network sockets.
You're looking for the Java-Objective C bridge, try looking at this article or on Apple's developer site. Be aware it is deprecated, that is it isn't being kept up to date with changes to Cocoa. But if you're just using it for an API passing standard Java datatypes you should be OK.