Using JNI functions, programmers can deal with the JVM from within an intrinsic method. As you can see in the previous example, each JNI intrinsic method receives a special argument as its first parameter: jnienv-It is a pointer to a special JNI data structure of type JNIENV_. One element of the JNI data structure is a pointer to an array generated by the JVM, and each element of the array is a pointer to a JNI function. Calls to the JNI function can be emitted from within the intrinsic method by undoing the reference to those pointers (the actual operation is simple). Each JVM implements the JNI functions in its own way, but their addresses are definitely located at predefined offsets.
using jnienv arguments, programmers can access a series of functions. These functions can be divided into the following categories:
Get version information
for class and object operations
control of global and local references to Java objects
Access instance fields and static fields
calling instance methods and static methods
executing string and array operations
The number of
JNI functions that generate and control Java exceptions is quite large and is no longer detailed here. Instead, I'll reveal some of the basics behind the use of these functions. For more detailed information, see the JNI documentation for your compiler.
If you look at the jni.h header file, you will find that within the #ifdef _cplusplus preprocessor condition, when compiled by the C + + compiler, the JNIENV_ structure is defined as a class. This class contains a large number of inline functions. With a simple and familiar syntax, these functions allow us to access the JNI function in a leisurely way. For example, the precedent contains the following line of code:
(*jenv)->releasestringutfchars (jenv, jmsg,msg);
It can be rewritten in C + + as follows:
Jenv-> Releasestringutfchars (JMSG,MSG);
You can note that you no longer need to undo two references to Jenv, and that the same pointer is no longer passed to the JNI function call as the first argument. In the rest of these examples, I'll use C + + style code.
1. Accessing Java strings
As an example of accessing the JNI function, consider the code above. Here, we use JNIEnv's argument jenv to access a Java string. The Java string is in Unicode format, so if you receive such a string and want to pass it to a non-Unicode function (such as printf ()), you must first convert it to an ASCII character using the JNI function Getstringutfchars (). The function can receive a Java string and convert it to a UTF-8 character (with 8-bit width to accommodate the ASCII value, or a 16-bit width to accommodate Unicode; if the contents of the original string are entirely ASCII, the resulting string is also ASCII).
Getstringutfchars is a field in the structure that jnienv indirectly points to, and this field is a pointer to a function. To access the JNI function, we use the traditional C syntax to invoke a function (through the pointer). Access to all JNI functions can be achieved using the above form.