| Java Native Interface Programming

## Java Strings

> The `jstring` type passed from Java to native code is not the regular C string type (char *). Therefore, trying to directly print a jstring will likely result in a VM crash.

>     /* DO NOT USE jstring THIS WAY !!! */
>     JNIEXPORT jstring JNICALL
>     Java_Prompt_getLine(JNIEnv *env, jobject obj, jstring prompt)
>     {
>       printf("%s", prompt);

> Your native method code must use JNI functions to convert Java strings to native strings. The JNI supports the conversion to and from native Unicode and UTF-8 strings. In particular, UTF-8 strings use the highest bit to signal multibyte characters; they are therefore upward compatible with 7-bit ASCII. In Java, UTF-8 strings are always 0-terminated.

> #### Accessing Java Strings

> To correctly print the string passed in from Java, your native method needs to call `GetStringUTFChars`. `GetStringUTFChars` converts the built-in unicode representation of a Java string into a UTF-8 string. If you are certain that the string only contains 7-bit ASCII characters, you can directly pass the string to regular C functions, such as `printf`, as is shown in `Prompt.c`.

>     JNIEXPORT jstring JNICALL
>     Java_Prompt_getLine(JNIEnv *env, jobject obj, jstring prompt)
>     {
>       char buf[128];
>       const char *str = (*env)->GetStringUTFChars(env, prompt, 0);
>       printf("%s", str);
>       (*env)->ReleaseStringUTFChars(env, prompt, str);

> Note that when your native code is finished using the UTF-8 string, it must call `ReleaseStringUTFChars`. `ReleaseStringUTFChars` informs the VM that the native method is finished with the string, so that the memory taken by the UTF-8 string can then be freed. Failing to call `ReleaseStringUTFChars` results in a memory leak. This will ultimately lead to system memory exhaustion.

> The native method can also construct a new string using the JNI function `NewStringUTF`. The following lines of code from `Java_Prompt_getLine` show this:

>       scanf("%s", buf);
>       return (*env)->NewStringUTF(env, buf);
>     }

> #### Using the JNIEnv Interface Pointer

> Native methods must access and manipulate Java objects, such as strings, through the `env` interface pointer. In C, this requires using the `env` pointer to reference the JNI function. Notice how the native method uses the `env` interface pointer to reference the two functions, `GetStringUTFChars` and `ReleaseStringUTFChars`, that it calls. In addition, env is passed as the first parameter to these functions.

> #### Other JNI Functions for Accessing Java Strings

> The JNI also provides functions to obtain the Unicode representation of Java strings. This is useful, for example, on those operating systems that support Unicode as the native format. There are also utility functions to obtain both the UTF-8 and Unicode length of Java strings.

> - `GetStringChars` takes the Java string and returns a pointer to an array of Unicode characters that comprise the string.
> - `ReleaseStringChars` releases the pointer to the array of Unicode characters.
> - `NewString` constructs a new `java.lang.String` object from an array of Unicode characters.
> - `GetStringLength` returns the length of a string that is comprised of an array of Unicode characters.
> - `GetStringUTFLength` returns the length of a string if it is represented in the UTF-8 format.

| Java Native Interface Programming