|
|
Interacting with Java from the Native Side |
When a Java application passes a string to a native method, it passes the string as ajstringtype. Thisjstringtype is different from the regular C string type (char *). If your code tries to print ajstringdirectly, it will likely result in a VM crash. For example, the following code segment incorrectly tries to print ajstringand may 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 upwards-compatible with 7-bit ASCII. In Java, UTF-8 strings are always 0-terminated.
Accessing Java Strings
Your native method needs to callGetStringUTFCharsto correctly print the string passed to it from a Java application.GetStringUTFCharsconverts the built-in Unicode representation of a Java string into a UTF-8 string. Once you are certain that the string only contains 7-bit ASCII characters, you can directly pass the string to regular C language functions, such asprintf, as is shown inPrompt.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: When your native code is finished using the UTF-8 string, it must callReleaseStringUTFChars.ReleaseStringUTFCharsinforms the VM that the native method is finished with the string so that the VM can free the memory taken by the UTF-8 string. Failing to callReleaseStringUTFCharsresults 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 fromJava_Prompt_getLineshow 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
envinterface pointer. In C, this requires using theenvpointer to reference the JNI function. Notice how the native method uses theenvinterface pointer to reference the two functions,GetStringUTFCharsandReleaseStringUTFChars, that it calls. Not only does the native method useenvas an interface pointer,envis 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.
GetStringCharstakes the Java string and returns a pointer to an array of Unicode characters that comprise the string.ReleaseStringCharsreleases the pointer to the array of Unicode characters.NewStringconstructs a newjava.lang.Stringobject from an array of Unicode characters.GetStringLengthreturns the length of a string that is comprised of an array of Unicode characters.GetStringUTFLengthreturns the length of a string if it is represented in the UTF-8 format.
|
|
Interacting with Java from the Native Side |