<== Chapter 5 -- Chapter 7 ==>
Chapter 6 - JNI C/C++ Interface
We now need to create an interface layer that will take our native function()
Java code and forward it to our native C/C++ implementation of the function. JNI Interface Code
- The first thing we want to do is add
#include <jni.h>
to get access to the JNI class - To ensure that the names declared in that portion of code have C linkage, and thus C++ name mangling is not performed we add these macro to surround the class
#ifdef __cplusplus
extern "C" {
#endif
.... // our code
#ifdef __cplusplus
}
#endif
- We are going to make a class next chapter so now is a good time to just declare the new C++ class at the top
#include "Tango_NDK_Tutorial.h"
static Tango_NDK_Tutorial app;
- Here we add a function call for each of the JNI native calls such as
JNIEXPORT void JNICALL
Java_com_demo_tutorial_tango_tango_1ndk_1tutorial_TangoJniNative_onCreate(
JNIEnv* env, jobject /*obj*/, jobject caller_activity) {
app.OnCreate(env, caller_activity);
}
- The format of these function calls that bring from Java to the native level follows a strict naming convention
- Always start your function with the return type of
JNIEXPORT < Return_Type > JNICALL
- the
< Return_Type >
can bevoid
,jint
,jstring
, etc
- the
- The name of function is made up of 3 different parts
- Package_Name
- Java_Class_Name
- Function_Name
- We concat them with underscores into the function name
- Example for the onCreate call:
Java_com_demo_tutorial_tango_tango_1ndk_1tutorial_MainActivity_onCreate
- Package_Name =>
com.demo.tutorial.tango.tango_ndk_tutorial
- NOTE: Since the package name has underscores in it you need to replace it with
_1
as seen in this example
- NOTE: Since the package name has underscores in it you need to replace it with
- Java_Class_Name =>
MainActivity
- Function_Name =>
onCreate
- Example for the onCreate call:
- Every
- JNIEnv* - Pointer to a structure storing all JNI function pointers. Provides most of the JNI functions. Your native functions all receive a JNIEnv as the first argument.
- The JNIEnv is used for thread-local storage. For this reason, you cannot share a JNIEnv between threads.
- jobject - This is a reference to an object of type
MainActivity
, almost like athis
of the Java Activity class instance
- JNIEnv* - Pointer to a structure storing all JNI function pointers. Provides most of the JNI functions. Your native functions all receive a JNIEnv as the first argument.
- We also call the
app
class we declared as a type of our future C++ class and run its internalOnCreate
method we will make soon.- Notice we try to help distinguish the Java and C++ functions by making the Java calls lowerCamelCase and the C++ UpperCamelCase as our naming convention
- Java ->
onCreate
- C++ ->
OnCreate
- Java ->
- Notice we try to help distinguish the Java and C++ functions by making the Java calls lowerCamelCase and the C++ UpperCamelCase as our naming convention
- For the
Java_com_demo_tutorial_tango_tango_1ndk_1tutorial_TangoJniNative_valueFromJNI
function we add a third parameter which is the Java int argument we sent the value5
. Here we take that value, add 1, and return it as ajint
type