Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

32-bit Java Accessibility on a 64-bit machine

I have a 32-bit app that makes use of Java Accessibility (WindowsAccessBridge-32.dll, via the Java Access Bridge), and works perfectly on a 32-bit machine, but fails on an x64 machine.

I believe I have tracked it down to one of the first calls after Windows_run:

getAccessibleContextFromHWND(hwnd, out vmId, out context)

defined as follows:

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("WindowsAccessBridge-32.dll", CallingConvention = CallingConvention.Cdecl)]
public extern static bool getAccessibleContextFromHWND(IntPtr hwnd, out Int32 vmID, out IntPtr acParent);

This call works fine on the 32-bit system, returning True, populating both vmId (with some 5-digit value, which), and context - whereas on the 64-bit system, it returns True, populates 'context', but returns '0' for vmId.

If I assume that 0 is valid (even though it's a random 5-digit number resembling a pointer on the 32-bit system), the next call still fails:

AccessibleContextInfo aci = new API.AccessibleContextInfo();
if (!getAccessibleContextInfo(vmId, context, ref aci))
  throw new Exception();

where:

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("WindowsAccessBridge-32.dll", CallingConvention = CallingConvention.Cdecl)]
public extern static bool getAccessibleContextInfo(Int32 vmID, IntPtr ac, ref AccessibleContextInfo info);

(I'm omitting the AccessibleContextInfo struct for brevity, but I can provide it if necessary).

I know that the libraries are working, because both JavaMonkey and JavaFerret work correctly. Furthermore, call to isJavaWindow works, returning 'true', or 'false' as appropriate, and I am linking to the correct DLL (WindowsAccessBridge-32).

Can anyone suggest what may be wrong here?

like image 930
Melllvar Avatar asked Dec 14 '11 01:12

Melllvar


People also ask

Can Java 32 and 64-bit coexist?

Yes, you can have both x64 bit and x32 bit Java installed. They won't create conflicts with with each other, as they're tied to the type of browser you're using.

How do I change my Java from 32-bit to 64-bit?

In the menu, click Settings > Active Profile. Click the Java icon and then the Advanced tab. Select 32-bit Java (default) or 64-bit Java.

Do I need 32 and 64-bit Java?

Java with 64 and/or 32 bit web browsersUsers that run Applets and Web Start applications through web browsers should choose the version of Java that matches their web browser. Generally speaking, 64 bit browsers run only 64 bit plugins and 32 bit browsers run only 32 bit plugins.


1 Answers

It appears that the problem is in the type of AccessibilityContext:

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("WindowsAccessBridge-32.dll", CallingConvention = CallingConvention.Cdecl)]
public extern static bool getAccessibleContextFromHWND(IntPtr hwnd, out Int32 vmID, out IntPtr acParent);

AccessibilityContext (acParent above), which I had incorrectly mapped as an IntPtr, is actually an Int32 when using the "legacy" WindowsAccessBridge.dll library (used under x86), and an Int64 when using the WOW64 WindowsAccessBridge-32.dll library.

So the upshot is, the code has to differ between x86 and WOW x64, and must be compiled separately for each. I do this by #define'ing WOW64 during x64 builds, always referencing the Int64 methods, and using "shim" methods on x86:

#if WOW64 // using x64

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("WindowsAccessBridge-32.dll", CallingConvention = CallingConvention.Cdecl)]
public extern static bool getAccessibleContextFromHWND(IntPtr hwnd, out Int32 vmID, out Int64 acParent);

#else // using x86

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("WindowsAccessBridge.dll", EntryPoint = "getAccessibleContextFromHWND", CallingConvention = CallingConvention.Cdecl)]
private extern static bool _getAccessibleContextFromHWND(IntPtr hwnd, out Int32 vmID, out Int32 acParent);

public static bool getAccessibleContextFromHWND(IntPtr hwnd, out Int32 vmID, out Int64 acParent)
{
  Int32 _acParent;

  bool retVal = _getAccessibleContextFromHWND(hwnd, out vmID, out _acParent);
  acParent = _acParent;

  return retVal;
}

#endif
like image 125
Melllvar Avatar answered Oct 16 '22 18:10

Melllvar