Previous | Next | Trail Map | Java Native Interface | Interacting with Java from the Native Side

JNI Programming in C++

The JNI provides a slightly cleaner interface for C++ programmers. The jni.h file contains a set of inline C++ functions. This allows the native method programmer to simply write:
jclass cls = env->FindClass("java/lang/String");
instead of:
jclass cls = (*env)->FindClass(env, "java/lang/String");

The extra level of indirection on env and the env argument to FindClass is hidden from the programmer. The C++ compiler simply expands out the C++ member function calls to their C counterparts; therefore, the resulting code is exactly the same.

The jni.h file also defines a set of dummy C++ classes to enforce the subtyping relationships among different variations of jobject types:

class _jobject {};
class _jclass : public _jobject {};
class _jthrowable : public _jobject {};
class _jstring : public _jobject {};
... /* more on jarray */

typedef _jobject *jobject;
typedef _jclass *jclass;
typedef _jthrowable *jthrowable;
typedef _jstring *jstring;
... /* more on jarray */
The C++ compiler is therefore better able than the C compiler to detect when incorrect types are passed to methods. For example, it is incorrect to pass a jobject to GetMethodID because GetMethodID expects a jclass. You can see this by examining the GetMethodID signature:
jmethodID GetMethodID(jclass clazz, const char *name, const char *sig);     
The C compiler treats jclass as the same as jobject because it makes this determination using the following typedef statement:
typedef jobject jclass;
Therefore a C compiler is not able to detect that you have mistakenly passed the method a jobject instead of jclass.

The added type safety in C++ comes with a small inconvenience. Recall from Accessing Java Arrays that in C you can fetch a Java string from an array of strings and directly assign the result to a jstring, as follows:

jstring jstr = (*env)->GetObjectArrayElement(env, arr, i);
In C++, however, you need to insert an explicit conversion of the Java string to jstring:
jstring jstr = (jstring)env->GetObjectArrayElement(arr, i);
You must make this explicit conversion because jstring is a subtype of jobject, which is the return type of GetObjectArrayElement.


Previous | Next | Trail Map | Java Native Interface | Interacting with Java from the Native Side