I've been playing around with the NDK recently, finding that many of the tutorials available online really don't help. I've been using this tutorial and I've got it running great.
However. Is this the correct use of the NDK? I mean if I have a game say with many classes all in C++ that I wish to port over to the android. Do I have to really manually change all my methods to the likes of:
JNIEXPORT jstring JNICALL Java_com_domain_ndk_NativeLib_hello
(JNIEnv * env, jobject obj) {
return (*env)->NewStringUTF(env, "Hello World!");
}
I can't see this being a very efficient way of porting my code over and I get the feeling I'm using the NDK wrong. I also have no idea how the NDK samples are supposed to work. Could anyone point me in the right direction?
Thanks
You do not need to change ANY of your existing methods to use the "auto-bound" JNI format. There aren't good examples in the Google NDK samples, but the Google SDK uses the other JNI binding method internally: Search for RegisterNatives() in the JNI docs. But even then, you really only need to create a wrapper for the few places that the Android SDK needs to talk to your library: user input/sensors in general, a draw callback, and possibly an "update" callback. Aside from that the rest of your app should remain untouched, except to get it to build.
To simplify things, I'd recommend you not use the native widgets; if you keep your game entirely in OpenGL, you can avoid going through Java to, e.g., draw textures to the screen, at least if you target 1.6 devices and newer, where the NDK has native bindings for OpenGL.
Contrary to some opinions (including those of Google), the NDK can and frequently is used for porting games to Android. I'm using it that way right now, in fact. You need to pass user events from Java to C++, and you need to have Java set up the basic GL context (there are no EGL bindings in the NDK), but you can do pretty much everything else in C++ with OpenGL and, once your basic Java messages are being passed to C++, you can (mostly) ignore Java. Thank goodness. :)
You'll still need to talk to Java for sound, and to get access to your files: Both still need to go through Java, and so you'll probably want to use "reverse JNI," where you call a Java function from C++. Also not hard, and there are examples all over the place.
I talk more about how to access your assets here: File Operations in Android NDK
Good luck.
I'd say your way isn't wrong, but be aware that passing data between Java and C/C++ code is a time consuming thing. Because of that I would suggest you write the most of the code actually in C/C++ and just call C/C++ functions from Java if it can't be avoided. For example you will need to pass data back for the GUI. Especially when you are programming a real time game I would avoid passing data between Java and C/C++ code too much. So just changing all the methods and then calling them in your Java code wouldn't be such a great idea.
Btw if you have to pass something back from C/C++ to Java, I would not pass it as a return value, but rather give the destination as a parameter in the function call.
The NDK is just a native C and C++ development environment for Android. Bionic (the Android version of libc) is more slightly more limited not by much. The only real complication is integrating you new component into the Android build tool chain. Android has a highly customized Makefile system. Downloading the source and looking at simple native components should give you an idea how to use it though.
Now if you want to integrate Java with C or C++ you will need to understand the Java Native Interface (JNI). You should be able to find good documentation of the JNI online.
The new release of the ndk (r5) now includes the capability to write apps entirely in native code.
Related
I am working on a project where I have some sensors and I want them to connect to a PC via USB. now they write there is a windows lib written in c and all functions are using the cdecl call convention of c and I have to be sure that if I programm in an other language (java!) that the call convention is given.
So I researched a bit and found a few tutorials to bind dlls in java and or use JNA. but this are all new things for me and I want to be sure, that it is possible (and maybe an example) - the device isn't that cheap and I want to know that before I buy it.
You can call C code from Java - there are no issues here.
Then, if you have something very specific in your C routines, you can always go via wrapper.
Take a look here.
http://jnicookbook.owsiak.org/recipe-No-018/
In this sample, you are calling C code that - in turn - calls another library.
You can also do it by linking your JNI code with some other library. Like here:
https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo023
There are plenty of options. When it comes to JNI vs. JNA. Make sure that JNA will be efficient enough. In general, JNA tends to be slower. Take a look here:
https://github.com/mkopsnc/keplerhacks/tree/master/jnijna
Hope this helps.
I don't post codes here - all the samples in JNI Cookbook are available from github.
I want to develop a 2D Game Engine, actually port an existing one.
The existing one is written in C++, so I wanted to use C++ + NDK to be able to use existing code and only change the OpenGL, Sound and the input part of the code.
I was looking some solutions and I saw some people using SWIG, but is that the good solution.
The code is written in C++11, uses lambda, variadic template, function pointers, i don't know how well the SWIG will manage the code.
My Question is. Is it worth to try to modify the code to usee with SWIG or NDK (because it looks like i cannot use NDK to instantiate C++ classes, and probably variadic templates will be even worse). Should i drop the idea to just use Java and rewrite the Engine?
This may be a bit of an odd question, but I would like to know if you can use Java inside c++14. I don't really care for GTK (I find it confusing and over complicated). Swing, however, is very easy to use, and you can get a working project very quickly. So I would like to know if you can use Java Swing inside c++, so I can use Swing as the foreground, as in what you see like graphics, and use c++ for the background, as in stuff you cant see, like calculations and objects and stuff. So if I can have c++ code tell Swing what to look like, or when to update, that would be very useful for the project I have in mind. Thanks in advance for any advice I may receive.
EDIT: Being able to use c++14 inside Java would be acceptable as well. Also, if anyone could get me example code also, this would be very helpful. Thanks!
You shouldn't run Java from C++, but rather C++ from Java. Oracle gives you a way to load native shared libraries, using JNI.
So you would create your view in Java, using Swing, then you would update your view by calling C++ functions that were pre-compiled and exported in a shared library.
That said, using JNI is quite tricky and the speed improvements of C++ might not be worth it; so you should consider using only Java (or only C++ and a library to create your GUI, such as Qt)
In which direction you go is a matter of taste (loading the JVM from a C++ program or loading DLLs from the JVM side).
Usually you go the way which is more logical, e.g. if you already have a C++ program you likely want to load the JVM from the C++ side. That would be your case. Especially if the Java you want to add is essentially "scripting" the C++ application.
If you already have a Java program and want to access a C++ DLL, you load the DLL from Java and write a simple JNI / native Java class.
In our times you would use tools like JNA for that (instead of JNI): https://github.com/java-native-access/jna
Or you can use SWIG to generate wrappers for your C++ classes: http://www.swig.org/
I'm trying to make a program like AutoHotKey, but with a graphical interface.
I'm using java.awt.Robot
Now I want to make the code for checking the state from a key (In AHK: getKeyState)
Of course somthing like a KeyListener without having focus.
I read already something with JNI and C++, but....
I can't find some information.
Can somebody help me??
There are lot of good JNI resources for starting out with JNI Programming like the Sun JNI Tutorial. Almost all Tutorials assume a good knowledge of C/C++ because the Java Native Interface (JNI) is the bridge between native C/C++ code, the Java Virtual Machine and everything running in there (meaning your Java Bytecode).
What you may want to do first is to find a key capturing library for your operating system of choice (you didn't mention anything specific here) in C++ and try that out as well as checking if there are already some Java bindings (libraries that use JNI and offer Java classes) to interact with. I didn't find any promising on a quick search unfortunately.
works perfect for windows 32/64 Bit. It's not necessary to integrate the dll files into the (eclipse)workspace / deployment process. Amazing Lib:
Hot stuff!
http://ksquared.de/blog/2011/07/java-global-system-hook/
Are there inexpensive or free gateways from .NET to Java? I'm looking at some data acquisition hardware which has drivers for C/C++ and .NET -- I really don't want to do any programming in .NET.
Update: I haven't done what I originally wanted to do, but I've done something similar, using JNA to encapsulate some functions from a DLL, in order to control a USB hardware device from Java. (the DLL comes from the device manufacturer) It works really nicely. Thanks!
You could also try to use JNA for accessing the native library. JNA provides Java programs easy access to native shared libraries (DLLs on Windows) without writing anything but Java codeāno JNI or native code is required. If their API is fairly straight foward, this might be the path of least resistance.
See their getting started guide where they call some native code (printf and GetSystemTime).
Well, there's JNBridge and EZ JCom, just from a Google search.
You could also use IKVM which is a slightly different approach.
(Any reason for not wanting to learn .NET, out of interest? It's a nice platform, and C# is a lovely language...)
If they have C++ versions of the drivers then you could write a wrapper around it using JNI and then load that in Java. JNI can be a bit of a pain, but it would let you use the C++ version of their drivers and not have to deal with .Net at all if you don't want.
I am partial to the recommendation to jump in the deep end with C# since it is so similar to Java. I did this and used IKVM to compile my favorite Java libs. to .NET assemblies and you get [nearly] all the core java runtime classes to boot, so if you tire of trying to find just the right C# collection type, you can always go back to java.util. (No generic collections though. Not sure why.)
Depending on what platform you're on, you have several choices for free IDEs too. For windows you can get Visual Studio Express for free but I also use SharpDevelop. You can also get the Mono IDE on Linux (and a few flavours of Unix, I think ?).
The C# learning curve is shallow if you already know Java. I only blew off 1.5 limbs on landmines that came out of nowhere for reasons I still don't understand, but workarounds were easy to come by. The worst thing about it was the darn developer docs which are AWFUL on account of being so slow. I really miss the snappiness of JavaDoc. Not only are the online docs incredibly slow, the problem is compounded by someones's iffy decision to put class summaries, constructors and methods/properties all on seperate pages so it just takes forever. Someone said to get the docs installer and install docs locally for a slightly improved experience. Not a bad idea I suppose.
I am author of jni4net, open source interprocess bridge between JVM and CLR. It's build on top of JNI and PInvoke. No C/C++ code needed. I hope it will help you.
If you have a Java application, the JNI mentioned by the others will be the way to go. You write some wrapper classes, and that's it.
If writing the wrappes is a too big task (depending on the number of methods you have to wrap), have a look at SWIG . I think it generates wrappers automatically, but I never actually used it.
If you want to code in the Java language, but you don't care if your program will run on the JRE/JVM, then you might as well use Microsoft J#. Basically, it's writing Java-Code wich is compiled to .NET-Bytecode and can use the .NET classes of the driver as well as your existing Java classes. With J# you will run into problems if your existing Java-code is newer than Java 1.4, look at this question on how to solve them.
From that point on, you could later add code in J#, C# or any other .NET language. However, you won't get back to the JRE/JVM easily.