Java applications are intended to be national language independent, just as they are intended to be operating system independent. If native methods are required on Windows, the Java application which implements the JNI methods will require special code when handling strings. Strings in Java are managed in Unicode. In Windows, strings are displayed and inputted in the current code page. Therefore, conversions are necessary if user input or output is required in a native method.
There are two JNI APIs to access Java strings from Windows native methods:
- GetStringUTFChars
- GetStringChars
The UTF format is defined by Java and matches the first 127 characters of the ASCII table. The UTF methods cannot generally be used because other national language characters in the UTF format cannot be understood by Windows APIs. However, these methods are very convenient for simple strings, such as debug messages, where a user is not required to convert Java strings directly to and from the C-style char* type.
The non-UTF (Unicode) JNI methods can be used but require special Windows APIs to convert them for display. The data produced by the Unicode methods is called wide-char or wchar* in Windows. The following Windows APIs are used to convert these strings:
- WideCharToMultiByte
- MultiByteToWideChar
This paper will develop simple examples showing how these methods are used.
|
In this section, we will create a test Java class with a native method displaying string arguments in a Windows message box. There is no reason for this function to be a native method, but it provides a simple example to illustrate how Java strings are displayed.
|
For more information on JNI see the JNI Specification available from Sun Microsystems. The example above is the complete test program including the native method, showParms0. This method will receive two strings which it will display in a Windows message box.
The native method is implemented in C in file, StringTest.c:
|
The JNI API, GetStringUTFChars
is used to create a C string from the Java string or jstring argument. The GetStringChars method creates a jchar array (Unicode characters) from the Java string.
The StringTest.dll is created by compiling the C source. The following compile statement uses the Microsoft Visual C++ compiler:
|
where c:/jdk1.1.6 is the path for the installed JDK.
The showParms0 function is passed the same string on both parameters. The reason for this is to show the difference between using the UTF methods and using the Unicode methods for converting strings. The class is run using the Java interpreter and the output is as follows:
java StringTest
This will show a window with an entry field, a pushbutton, and a listbox. As a test, some non-English national language characters are entered along with the word HELLO as follows:
Clicking "Send" calls the showParms0 native method which shows two message boxes.
The string characters from the message box were converted using the UTF method. Only the HELLO characters are correct. The second message box displays strings from the Unicode methods.
All characters are displayed correctly.
|
This example will accept command line parameters and display them in the Label of the Frame of the Java application. The Java code is written to show the argument strings:
|
The application can be executed using the java.exe interpreter:
java MyApp First second last
which shows the frame window with the string parameters:
Passing parameters to the Java class main from C requires creating a string array from the parameters and passing the array to CallStaticVoidMethod
. The following code will launch a Java application from a Windows .EXE and passes command line parameters to the Java program.
|
The __argc and __argv variables are convenient for accessing the command line parameters in a WinMain
.EXE and are equivalent to argc and argv in a regular main
.EXE.
The MyApp.exe is built using the following command line for Microsoft Visual C++:
cl -Ic:/jdk1.1.6/include -Ic:/jdk1.1.6/include/win32 -MT MyApp.c c:/jdk1.1.6/lib/javai.lib
c:/jdk1.1.6 is where the JDK is installed. If MyApp.exe is executed from a Windows command line, any parameters are displayed in the Java window.
In the methods presented above, the UTF strings methods are used to access and create Java strings. These methods cannot be used for other national language character sets like the double-byte character set (DBCS) or other national language characters. For example, if the previous example's MyApp.exe is executed from the command line as follows:
MyApp d?os?enregistr?
The following is shown in the GUI:
The accented e's are not shown correctly because they are above 127 in the ASCII table. Using Unicode along with the appropriate JNI and Windows APIs will correct this problem.
Java strings can be converted to and from Unicode character arrays using the appropriate JNI APIs. Once the Java Strings are obtained in Unicode, the API MultiByteToWideChar
converts a Windows string to a Unicode character array. The following function can be used to create a Java String from a multi-byte string.
|
In the above function, MultiByteToWideChar
is called twice. The first call determines the number of Unicode characters, which is then used to compute the size of the memory allocation to hold the character array. The second call performs the conversion into that array. The Java string is created from the array by calling the NewString
method. Now the function will be used to correct the problem of displaying the wrong characters introduced in the example. The above WindowsTojstring
function is added to the C code and the following line is changed from:
str = (*env)->NewStringUTF( env, __argv[i] ); to: str = Windows2jstring( env, __argv[i] );
A recompile and re-execute now shows the parameters correctly.
|
This paper presented examples for implementing native methods dealing with conversion of strings for an NLS-enabled Java program environment. Strings are maintained in Unicode in Java and must be converted appropriately using the following JNI APIs:
- NewString
- GetStringChars
- ReleaseStringChars
- GetStringLength
and the following Windows APIs:
- MultiByteToWideChar
- WideCharToMultiByte
See the Java Native Interface Specification available from Sun Microsystems for more information on JNI.
|
|
David Wendt is an IBM Programmer for WebSphere Studio in Research Triangle Park, NC. He can be reached at wendt@us.ibm.com. |