This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.
|
java911@microsoft.com Download the code (13KB) |
Parlez-vous J/Direct?
My February column covered the differences between the various Java native interfaces:
J/Direct, COM, RNI, and JNI. This month I'll delve more deeply into J/Direct to address a few of the questions that weren't answered in February. Keep in mind that most of the
J/Direct declarations demonstrated here are conveniently available by simply importing classes from the package com.ms.win32. In fact, com.ms.win32 serves as a good point of reference if you're having trouble.
How do I call a function that returns a DWORD value through a pointer (for example, GetDiskFreeSpace)?
|
WINBASEAPI BOOL WINAPI GetDiskFreeSpace(LPCTSTR lpRootPathName,
LPDWORD lpSectorsPerCluster,
LPDWORD lpBytesPerSector,
LPDWORD lpNumberOfFreeClusters,
LPDWORD lpTotalNumberOfClusters)
GetDiskFreeSpace takes the path to the root of a drive and the addresses of several DWORD variables. If the function returns TRUE, the DWORD variables have been modified to contain appropriate values.
WINBASEAPI DWORD WINAPI GetEnvironmentVariable(LPCTSTR lpName,
LPTSTR lpBuffer,
DWORD nSize)
The function takes the name of an environment variable like PATH and returns the current value of the variable in the lpBuffer character buffer. The nSize parameter specifies the size of the buffer in characters.
Java Tip of the Month If you're having trouble getting J/Direct code to work, double-check your @dll tags. Make sure you've linked to the right DLLs and that you're using the auto keyword (if necessary). If you run out of ideas, you may want to surf over to the J/Direct troubleshooting page: http://www.microsoft.com/java/sdk/default.htm
|
|
The @dll.structmap tag can be used to specify fixed-length arrays and character buffers. For example, consider the kernel32.dll GetVersionEx function. It takes only an OSVERSIONINFO structure as an argument. OSVERSIONINFO looks roughly like this: |
|
The corresponding J/Direct declaration of this structure is shown in Figure 4. Notice how the @dll.structmap tag specifies that the csdVersion string is a 128-character, fixed-length string where the TCHAR type specifier is defined as a 16-bit Unicode character on Windows NT and as an 8-bit ANSI character on Windows 95.
The WinJava sample application ties together all of the J/Direct features I've discussed in this column. It also demonstrates two additional features. The first is the use of @dll.import on an entire class. In the main WinJava class, I declare a tag marking the class as @dll.import("USER32",auto). This is simply shorthand for "import all static native methods in this class from user32.dll." This saves quite a bit of typing. The second new concept is brought into play when the WinJava window class is registered. In Figure 5, my callback was only in use for the duration of the native call. Since a window class continues to use the WNDPROC callback long after the class has been registered, you need to make sure that the WNDPROC doesn't get moved or reclaimed by the garbage collector in the meantime. I do this by allocating a root handle to the WNDPROC object (in this case, WinJavaWndProc) using com.ms.dll.Root.alloc, and then specifying the address of that object (determined by com.ms.dll.DllLib.addrOf) as the lpfnWndProc member of the WNDCLASSEX structure. |