2011-12-14 10 views
5

Tengo una aplicación de 32 bits que hace uso de Java Accessibility (WindowsAccessBridge-32.dll, a través del puente de acceso Java), y funciona perfectamente en una máquina de 32 bits , pero falla en una máquina x64.Java Accesibilidad de 32 bits en una máquina de 64 bits

Creo que he rastreado hasta una de las primeras llamadas después Windows_run:

getAccessibleContextFromHWND(hwnd, out vmId, out context) 

definido de la siguiente manera:

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

Esta llamada funciona bien en el sistema de 32 bits, volviendo Es cierto que rellena vmId (con un valor de 5 dígitos, que) y el contexto, mientras que en el sistema de 64 bits, devuelve True, rellena 'context', pero devuelve '0' para vmId.

Si asumo que 0 es válida (aunque es un número de 5 dígitos al azar parecido a un puntero en el sistema de 32 bits), la siguiente llamada sigue fallando:

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

donde:

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

(Estoy omitiendo la estructura AccessibleContextInfo para abreviar, pero puedo proporcionarla si es necesario).

Sé que las bibliotecas funcionan, porque tanto JavaMonkey como JavaFerret funcionan correctamente. Además, la llamada a isJavaWindow funciona, devolviendo 'verdadero' o 'falso' según corresponda, y estoy enlazando con la DLL correcta (WindowsAccessBridge-32).

¿Alguien puede sugerir qué puede estar mal aquí?

Respuesta

4

Parece que el problema está en el tipo de 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 anterior), que había mapeado incorrectamente como IntPtr, es en realidad un Int32 cuando se usa la biblioteca "heredada" WindowsAccessBridge.dll (utilizada en x86), y un Int64 cuando se usa la biblioteca WOW64 WindowsAccessBridge-32.dll .

Así que el resultado es que el código tiene para diferir entre x86 y WOW x64, y se debe compilar por separado para cada uno. Lo hago por # definiendo con WOW64 durante 64 construye, siempre hace referencia a los métodos Int64, y el uso de "corrección" métodos en 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

Every AccessibleContext IntPtr debe reemplazarse por long, incluidos, entre otros, getAccessibleContextFromHWND, getAccessibleParentFromContext, getAccessibleChildFromContext, getAccessibleTextInfo. .. – HelloSam

0

Si utiliza una JVM de 64 bits con una versión de 32 bits del puente de acceso Java, no funcionará correctamente. Necesita una versión de 64 bits del puente de acceso que se ha lanzado recientemente. ver http://blogs.oracle.com/korn/entry/java_access_bridge_v2_0 Para obtener instrucciones sobre la instalación de una copia de 32 bits del puente de acceso para su uso con 32 bits en 64 bits de Windows de JRE ver http://www.travisroth.com/2009/07/03/java-access-bridge-and-64-bit-windows/

+0

estoy usando 2.0.2, y han probado tanto de 32 bits y 64 bits de JVM éxito: JVM de 64 bits con 32 bits JavaMonkey funciona JVM de 64 bits con 64 bits JavaMonkey funciona 32- bit JVM con JavaMonkey de 32 bits funciona Así que el JavaBridge parece funcionar bien, por lo que puedo decir, en todos los casos – Melllvar

0

La llamada a 'initializeAccessBridge' requiere que tenga un suministro de mensajes ventanas activas . Dentro de 'initializeAccessBridge', (eventualmente) crea una ventana de diálogo oculta (usando CreateDialog). Una vez que se crea el cuadro de diálogo, realiza un mensaje de correo electrónico con un mensaje registrado. El lado JavaVM del puente de acceso responde a este mensaje y envía otro mensaje al diálogo que se creó (parece ser un saludo de tipo 'hola' entre su aplicación y la máquina virtual de Java).Como tal, si su aplicación no tiene una bomba de mensajes activa, su aplicación nunca recibirá el mensaje de devolución de JavaVM.

+0

Gracias por responder, pero tenga en cuenta que ya respondí mi propia pregunta;) – Melllvar

+0

Lo siento, he estado peleando con esto yo mismo y esto me dejó alucinado cuando Lo vi porque no hay documentación que diga esto. –

Cuestiones relacionadas