views:

130

answers:

4

Hey,

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

+1  A: 

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.

doron
So that is the correct way of using it? Got any hints on getting the NDK samples to run?
ing0
+2  A: 

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.

Pandoro
ing0
Well I'd say yes it is possible. But that does depend on whether your app needs to be fast or not. A simple puzzle game? Sure! But if you are talking about a game with complex graphics I'd really consider writing new code to adjust the structure so that it fits Android better.
Pandoro
A: 

The android NDK is NOT for porting apps to android. It is for making time sensitive code able to run natively.

Falmarri
I didn't say it was, but I believe it can be used to do this.
ing0
+2  A: 

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: http://stackoverflow.com/questions/1992953/file-operations-in-android-ndk/3789091#3789091

Good luck.

SomeCallMeTim
Hey thanks for that, great info for what I thought was a dead question on here! :) I haven't used the NDK too much yet but I will update how I get on with it.
ing0