问题描述
我有一个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位机器上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!