32位Java可访问64位机器上 [英] 32-bit Java Accessibility on a 64-bit machine

查看:356
本文介绍了32位Java可访问64位机器上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个32位的应用程序,利用Java的可访问性(WindowsAccessBridge-32.DLL,通过Java访问桥),并完美的作品在32位机器上,但未能在x64机器上。

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.

我相信我已经跟踪它到Windows_run后的第一个电话中的一个:

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

getAccessibleContextFromHWND(hwnd, out vmId, out context)

定义如下:

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

这调用工作正常在32位系统上,返回true,填充都VMID(有一些5位数字值,)和上下文 - 而在64位系统上,它返回True,填充语境,但对于VMID返回0

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.

如果我假设0是有效的(即使它是类似于在32位系统上的指针随机的5位数字),下一次调用仍然失败:

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);



(我省略AccessibleContextInfo结构为简洁起见,但如果需要,我可以提供它)。

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

我知道库工作,因为JavaMonkey和JavaFerret都正常工作。此外,来电isJavaWindow作品,返回真或假为合适的,我连接到正确的DLL(WindowsAccessBridge-32)。

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?

推荐答案

看来,问题出在AccessibilityContext类型:

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以上),我曾错误地映射为一个IntPtr,实际上是一个Int32使用时,使用WOW64 WindowsAccessBridge-32.DLL库时的遗留WindowsAccessBridge.dll库(x86下使用),以及一个Int64。

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.

所以结果是,代码的应用于x86和x64的WOW有所不同,因此必须针对每个单独编译。我通过#64时define'ing WOW64为此建立,总是引用Int64的方法,并采用垫片的方法在x86:

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

这篇关于32位Java可访问64位机器上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆