JDirect
 In this topic

*Calling the ANSI Version of a DLL Function

*Calling the Unicode Version of a DLL Function

*Calling the Optimal Version of a DLL Function

 

JDirect    PreviousJDirectNext
About J/Direct     Previous JDirect Next

 


How the VM Chooses Between ANSI and Unicode

The simple MessageBox example that starts this document glosses over a subtle, but important fact: USER32 does not export a function named MessageBox. Because the MessageBox function takes a string, it (like all Win32 functions that deal with strings) must exist in two versions: an ANSI version and a Unicode version (named MessageBoxA and MessageBoxW, respectively). When you code a call to MessageBox in C or C++, the MessageBox "function" you call is actually a macro that expands to either MessageBoxA or MessageBoxW, depending on whether the UNICODE macro is defined.

Calling the ANSI Version of a DLL Function

By default, the Microsoft Win32 VM for Java assumes that the ANSI version of MessageBox is the one that is needed. If you import the MessageBox function using @dll.import (without a modifier) as follows,


  /** @dll.import("USER32") */
  static native int MessageBox(int hwnd, String text, 
                               String title, int style);

the Microsoft VM will go through the following steps.

  1. The strings "text" and "title" are converted to ANSI null-terminated strings.
  2. The VM attempts to find an export named MessageBox in USER32.DLL.
  3. This attempt fails. The VM then appends an "A" onto the name and looks for an export named MessageBoxA.
  4. This attempt succeeds, and the VM invokes the MessageBoxA function.

Calling the Unicode Version of a DLL Function

Suppose, instead, you wanted to call the Unicode version of MessageBox. You can do this by using the unicode modifier with the @dll.import directive:


  /** @dll.import("USER32",unicode) */
  static native int MessageBox(int hwnd, String text, String title,
                               int style);

Since the unicode modifier is present, the Microsoft VM will go through the following steps.

  1. The strings "text" and "title" are converted to Unicode null-terminated strings.
  2. The VM attempts to find an export named MessageBox in USER32.DLL.
  3. This attempt fails. The VM appends a "W" onto the name and looks for an export named MessageBoxW.
  4. This attempt succeeds, and the VM invokes the MessageBoxW function.

Calling the Optimal Version of a DLL Function

Unfortunately, neither of these situations is an ideal way to invoke the Win32 functions. Using the default ANSI mode allows your code to run on any Win32 platform, but causes unnecessary performance penalties on fully Unicode systems such as Microsoft® Windows® NT. Using the unicode modifier removes the performance penalty but restricts you to running on systems that implement the Unicode API. Fortunately, you can use the auto modifier with the @dll.import directive to call the optimal version of a DLL function based on the host operating system.

Using the auto modifier gives you the best of both worlds. The following example shows how to call the optimal version of the MessageBox function.


  /** @dll.import("USER32",auto) */
  static native int MessageBox(int hwnd, String text, String title, 
                               int style);

When the auto modifier is present, the Microsoft VM determines at run time whether the underlying platform supports the Unicode APIs. If Unicode is supported, the Microsoft VM acts as if the unicode modifier had been specified. Otherwise, the Microsoft VM behaves as if the ansi modifier had been specified. Thus, the auto modifier allows you to generate a single binary which runs well on both ANSI and Unicode Windows systems using the optimal API set available on the given platform.

In general, the auto modifier should be used whenever you call Windows API functions. If you are calling your own DLLs, select either ansi (the default) or unicode depending on your needs.

Here are the details of how the Microsoft VM decides whether to use ANSI or Unicode when you use the auto modifier.

  1. The VM opens the registry key HKEY_LOCAL_MACHINE\Software\Microsoft\Java VM and looks for the DWORD-named value DllImportDefaultType. This value can be one of the following:

    2 - ANSI: Uses the ANSI version always.

    3 - Unicode: Uses the Unicode version always.

    4 - Platform: Uses ANSI or Unicode depending on the platform.

  2. If the key does not exist, or if it is set to 4 (indicating platform), the VM calls the Win32 GetVersion function and examines the high bit to determine whether the underlying platform is Microsoft® Windows® 95 or Microsoft® Windows® NT. If the platform is Windows 95, ANSI mode is used. Otherwise, Unicode mode is used.

It is not necessary to set the DllImportDefaultType registry key yourself. It exists primarily so that the installation program can set the appropriate choice on future Windows platforms. You can programatically query the preferred mode on your platform by reading the com.ms.dll.DllLib.systemDefaultCharSize field. This field will be set to 1 on ANSI systems, 2 on Unicode systems.

The ansi, unicode, and auto modifiers can also be used with the @dll.struct directive.

Top © 1998 Microsoft Corporation. All rights reserved. Terms of use.