32-битная доступность Java на 64-битной машине - PullRequest
5 голосов
/ 14 декабря 2011

У меня есть 32-разрядное приложение, которое использует Java Accessibility (WindowsAccessBridge-32.dll, через Java Access Bridge) и отлично работает на 32-разрядной машине, но не работает на машине x64.

Я полагаю, что отследил его до одного из первых вызовов после 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-битномsystem, возвращая True, заполняет как vmId (с некоторым 5-значным значением, которое), так и context - тогда как в 64-битной системе он возвращает True, заполняет «context», но возвращает «0» для vmId.

Если я предполагаю, что 0 является действительным (даже если это случайное 5-значное число, напоминающее указатель в 32-разрядной системе), следующий вызов все равно не будет выполнен:

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

где:

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

(я для краткости опускаю структуру AccessibleContextInfo, но могу предоставить ее при необходимости).

Я знаю, что библиотеки работают, потому что и JavaMonkey, и JavaFerret работают правильно.Кроме того, вызов isJavaWindow работает, возвращая «true» или «false» в зависимости от ситуации, и я ссылаюсь на правильную DLL (WindowsAccessBridge-32).

Может кто-нибудь подсказать, что здесь может быть не так?

Ответы [ 3 ]

4 голосов
/ 17 декабря 2011

Похоже, что проблема в типе 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 при использовании «устаревшего» WindowsAccessBridgeбиблиотека .dll (используется под x86) и Int64 при использовании библиотеки WOW64 WindowsAccessBridge-32.dll.

Таким образом, код имеет , чтобы отличаться между x86 и WOW x64, и должен быть скомпилирован отдельно для каждого.Я делаю это, # определяя WOW64 во время сборки x64, всегда ссылаясь на методы Int64 и используя методы "shim" на 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
0 голосов
/ 14 августа 2014

Вызов 'initializeAccessBridge' ТРЕБУЕТ, чтобы у вас был активный насос сообщений Windows. Внутри 'initializeAccessBridge' он (в конце концов) создает скрытое диалоговое окно (используя CreateDialog). Как только диалог создан, он выполняет PostMessage с зарегистрированным сообщением. Сторона JavaVM моста доступа отвечает на это сообщение и отправляет еще одно сообщение в созданное диалоговое окно (оно выглядит как рукопожатие типа «привет» между вашим приложением и виртуальной машиной Java). Таким образом, если ваше приложение не имеет активной рассылки сообщений, ваше приложение никогда не получит ответное сообщение от JavaVM.

0 голосов
/ 14 декабря 2011

Если вы используете 64-битную JVM с 32-битной версией моста доступа Java, он не будет работать правильно.Вам нужна 64-битная версия моста доступа, которая была недавно выпущена.см. http://blogs.oracle.com/korn/entry/java_access_bridge_v2_0 Инструкции по установке 32-битной копии моста доступа для использования с 32-битными JRE под 64-битными окнами см. http://www.travisroth.com/2009/07/03/java-access-bridge-and-64-bit-windows/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...