2011-12-14 10 views
5

Mam 32-bitową aplikację, która korzysta z Java Accessibility (WindowsAccessBridge-32.dll, przez Java Access Bridge) i działa doskonale na 32-bitowej maszynie , ale kończy się niepowodzeniem na maszynie x64.32-bitowa dostępność języka Java na 64-bitowym komputerze

wierzę, że śledzone ją w dół do jednego z pierwszych zaproszeń po Windows_run:

getAccessibleContextFromHWND(hwnd, out vmId, out context) 

zdefiniowane następująco:

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

toll działa poprawnie w systemie 32-bitowym, wracając Prawda, zapełniając zarówno vmId (z pewną 5-cyfrową wartością, która), jak i kontekstem - podczas gdy w systemie 64-bitowym zwraca True, wypełnia "kontekst", ale zwraca "0" dla vmId.

Jeśli założymy, że 0 jest ważny (choć jest to przypadkowy 5-cyfrowy numer przypominający wskaźnik na systemie 32-bitowym), następne wywołanie nadal kończy się niepowodzeniem:

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

gdzie:

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

(Pomijam strukturę AccessibleContextInfo dla zwięzłości, ale mogę ją podać w razie potrzeby).

Wiem, że biblioteki działają, ponieważ zarówno JavaMonkey, jak i JavaFerret działają poprawnie. Ponadto wywołanie funkcji isJavaWindow działa, zwracając "true" lub "false" w zależności od potrzeb i łączę się z poprawną biblioteką DLL (WindowsAccessBridge-32).

Czy ktoś może sugerować, co może być nie tak?

Odpowiedz

4

Wydaje się, że problem jest w rodzaju 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 powyżej), który niepoprawnie zamapowany jako IntPtr, jest w rzeczywistości Int32 podczas korzystania z "starszej" biblioteki WindowsAccessBridge.dll (używane pod x86) i Int64 podczas korzystania z biblioteki WOW64 WindowsAccessBridge-32.dll .

W efekcie kod ma, aby odróżnić x86 od WOW x64 i musi być skompilowany osobno dla każdego z nich. Robię to przez # define'ing WOW64 podczas x64 buduje, zawsze przedstawieniu metod Int64 i używając „podkładek” metod na 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

Każdy AccessibleContext IntPtr muszą być zastąpione przez długi, włączając, lecz nie ograniczając się do getAccessibleContextFromHWND, getAccessibleParentFromContext, getAccessibleChildFromContext, getAccessibleTextInfo. .. – HelloSam

0

Jeśli korzystasz z 64-bitowej maszyny JVM z 32-bitową wersją mostu Java Access, nie będzie działać poprawnie. Potrzebujesz 64-bitowej wersji mostka dostępowego, który został niedawno wydany. zobacz http://blogs.oracle.com/korn/entry/java_access_bridge_v2_0 Instrukcje dotyczące instalowania kopii 32 bitową mostu dostępu do użytku z 32 nieco poniżej 64 okien JRE za bit zobaczyć http://www.travisroth.com/2009/07/03/java-access-bridge-and-64-bit-windows/

+0

używam 2.0.2 i przetestowali zarówno 32-bitowe i 64-bitowe JVM z powodzeniem: 64-bitowe JVM z 32-bitowym JavaMonkey działa 64-bitowe JVM z 64-bitowym JavaMonkey działa 32- bit JVM z 32-bitowym JavaMonkey działa Więc JavaBridge wydaje się działać dobrze, z tego co mogę powiedzieć, we wszystkich przypadkach – Melllvar

0

Wezwanie do „initializeAccessBridge” wymagane jest posiadanie aktywnego okna wiadomość pompę . Wewnątrz "initializeAccessBridge" (w końcu) tworzy ukryte okno dialogowe (używając CreateDialog). Po utworzeniu okna dialogowego wykonuje on PostMessage z zarejestrowanym komunikatem. Strona JavaVM mostka dostępu odpowiada na tę wiadomość i przesyła kolejną wiadomość do okna dialogowego, które zostało utworzone (wydaje się, że jest to handshake typu "cześć" między aplikacją a maszyną wirtualną Java).W związku z tym, jeśli twoja aplikacja nie ma aktywnej pompy komunikatów, wiadomość zwrotna z JavaVM nigdy nie zostanie odebrana przez twoją aplikację.

+0

Dziękuję za odpowiedź, ale zauważ, że już odpowiedziałem na moje pytanie;) – Melllvar

+0

Przepraszam, walczyłem z tym sam i to dmuchnęło mi w głowę, kiedy widziałem to, ponieważ nie ma dokumentacji mówiącej o tym. –

Powiązane problemy