2013-07-10 1 views
0

32 비트 java에서 완벽하게 작동하지만 64 비트 jvm에서는 작동하지 않는 Java 원시 액세스를 사용하는 간단한 프로그램이 있습니다. 이것은 코드LastErrorException : [1413] 64Bit 창에서 JNA의 색인이 잘못되었습니다.

Day of the Week 4 
Year : 2013 
Processor Type : 8664 
System Metrics : 960 
Setting HWPointer 
Getting current wnd proc ptr 
Exception in thread "main" com.sun.jna.LastErrorException: [1413] Invalid index. 
    at com.sun.jna.Native.invokeLong(Native Method) 
    at com.sun.jna.Function.invoke(Function.java:386) 
    at com.sun.jna.Function.invoke(Function.java:315) 
    at com.sun.jna.Library$Handler.invoke(Library.java:212) 
    at com.sun.proxy.$Proxy2.GetWindowLongW(Unknown Source) 
    at SutdownJna.main(SutdownJna.java:71) 

다음과 같이

64 개 비트 OS 및 JVM의 프로그램 출력된다.

public class SutdownJna { 

    public interface User33 extends User32 { 

//  static int GWL_WNDPROC = -4; 
     User33 INSTANCE = (User33) Native.loadLibrary("user32", User33.class, 
       W32APIOptions.DEFAULT_OPTIONS); 

     interface WNDPROC extends StdCallLibrary.StdCallCallback { 

      LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam); 
     } 

     LONG_PTR GetWindowLongW(HWND hWnd, int nIndex) throws LastErrorException; 

     LRESULT CallWindowProcW(LONG_PTR proc, HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam); 

     LONG_PTR SetWindowLongW(HWND hWnd, int nIndex, User33.WNDPROC wndProc); 
    } 
    public static final int WM_QUERYENDSESSION = 0x11; 

    public static void main(String[] args) { 
     User33.WNDPROC wndProcCallbackListener = null; 

     final JFrame frame = new JFrame("Shutdown Test"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 


     Kernel32 INSTANCE = (Kernel32) Native 
       .loadLibrary("Kernel32", Kernel32.class); 

     SYSTEMTIME time = new SYSTEMTIME(); 
     INSTANCE.GetSystemTime(time); 
     System.out.println("Day of the Week " + time.wDayOfWeek); 
     System.out.println("Year : " + time.wYear); 

     SYSTEM_INFO systeminfo = new SYSTEM_INFO(); 
     INSTANCE.GetSystemInfo(systeminfo); 
     System.out.println("Processor Type : " + systeminfo.dwProcessorType); 
     System.out.println("System Metrics : " + User32.INSTANCE.GetSystemMetrics(1)); 
     HWND hwnd = new HWND(); 
     System.out.println("Setting HWPointer"); 
     hwnd.setPointer(Native.getComponentPointer(frame)); 
     System.out.println("Getting current wnd proc ptr"); 
     final LONG_PTR prevWndProc = User33.INSTANCE.GetWindowLongW(hwnd, User33.GWL_WNDPROC); 
     System.out.println("Creating new wnd proc ptr"); 
     User33.WNDPROC proc = new User33.WNDPROC() { 
      public LRESULT callback(HWND wnd, int msg, WPARAM param, LPARAM param2) { 
       System.out.println("Received msg : " + msg); 
       if (msg != WM_QUERYENDSESSION) { 
        return User33.INSTANCE.CallWindowProcW(prevWndProc, wnd, msg, param, param2); 
       } else { 
        return new LRESULT(0); 
       } 
      } 
     }; 

     System.out.println("Setting new Proc Handler " + proc); 
     User33.INSTANCE.SetWindowLongW(hwnd, User33.GWL_WNDPROC, proc); 

    } 
} 

테스트는 Windows 7 32 비트 및 Windows 7 64 비트에서 이루어졌습니다.

답변

1

GetWindowLongPtr에 대한 문서를 참조하십시오. 64 비트 시스템에서 64 비트가되는 포인터 값을 검색하고 있습니다. GetWindowLongPtr이 32 비트 매크로 또는 함수인지 여부는 명확하지 않습니다 (매크로 인 경우에만 UnsatisfiedLinkError이 표시됨).