关于本站

联系我们

免责声明

 首页 | 要闻 | 热点 | 研发 测试 安全 | 人物 企业 | 技术 产品 | 互联网 人才 | 信息化 开源 | Dotnet Java | SOA 中间件 业务平台 | 图片头条
通过Function类来实现Win32 API,让Java代码代替JNI
发布时间:2008-5-13 8:16:30    Java
  
在swt extension中,引入了function这个类。基本上所有的win32 jni库都有这个类,用来直接操纵win32 的部分api。有了这个class,我们不用编写jni,就可以实现某些简单的,甚至是较复杂的win32 api。这里我们就以enumwindows这个api举例,看看怎么java来执行这个win32 api。
     private static final string funtion_enumwindows = "enumwindows";
     private static final string user32_lib = "user32";
     private static list windowslist = new arraylist();
    
     public static int[] enumwindows()
     {
     windowslist.clear();
     callback callback = new callback(windows.class, "enumwindowsproc", 2);
     int address = callback.getaddress();
     if (address != 0)
     {
     try
     {
     function function = new function(user32_lib, funtion_enumwindows);
     function.invoke_i(address, 0);
     function.close();
     } catch (exception e)
     {
     swt.error(swt.error_invalid_argument);
     }
     callback.dispose();
     }
     int[] handles = new int[windowslist.size()];
     for (int i = 0; i windowslist.size(); i++)
     handles[i] = ((long) windowslist.get(i)).value;
     return handles;
     }
     private static int enumwindowsproc(int hwnd, int lparam)
     {
     windowslist.add(new long(hwnd));
     return 1;
     }enumwindows是用来遍历windows窗口的api,它需要传入一个返回boolean值的callback的地址作为参数。实际上在c里面,一个boolean值无非就是是否非0,如果为0,则为false,不为0,则为true。我们只需要new 一个function实例,传入这个api所在的lib和api名字,然后执行invoke方法就ok了,在function里面,可以最多执行含有4个简单类型参数的api。
     让我们再来看看findwindowex这个api,它需要传入2个int变量和2个字符串指针,根据swt的设计,我们是可以将java的字符串转换为指针的,因此通过function我们也可以实现这个api:
     private static final string funtion_findwindowex = extension.isunicode ? "findwindowexw"
     : "findwindowexa";
     private static final string user32_lib = "user32";
    
     public static int findwindowex(int parent, int hwndchildafter, string classname,
     string windowname)
     {
     int result = 0;
     int lpclassname = 0;
     int lpwindowname = 0;
     int hheap = extension.getprocessheap();
     if (classname != null)
     {
     tchar buffer = new tchar(0, classname, true);
     int bytecount = buffer.length() * tchar.sizeof;
     lpclassname = extension.heapalloc(hheap, extension.heap_zero_memory, bytecount);
     extension.movememory(lpclassname, buffer, bytecount);
     }
     if (windowname != null)
     {
     tchar buffer = new tchar(0, windowname, true);
     int bytecount = buffer.length() * tchar.sizeof;
     lpwindowname = extension.heapalloc(hheap, extension.heap_zero_memory, bytecount);
     extension.movememory(lpwindowname, buffer, bytecount);
     }
     try
     {
     function function = new function(user32_lib, funtion_findwindowex);
     result = function.invoke_i(parent, hwndchildafter, lpclassname, lpwindowname);
     function.close();
     } catch (exception e)
     {
     swt.error(swt.error_invalid_argument);
     }
     if (lpclassname != 0) extension.heapfree(hheap, 0, lpclassname);
     if (lpwindowname != 0) extension.heapfree(hheap, 0, lpwindowname);
     return result;
     }其实像这种简单参数类型的api,win32 里还有很多,我们完全不必为其专门编写jni,只需使用熟悉的java即可。虽然不是调用全部的api,但大部分常用的api都是没有问题的,关键是如何灵活运用。现在的大型商业rcp应用中,其实多多少少都参和了jni,用于提升对用户的友好性和软件的执行性能,毕竟java天生就是客户端开发的矮子。对于jni,我们既不能一味排斥,也不能滥用,要把握一个平衡点,使之成为java客户端开发的利器。


注:IT公司速查网所有信息来自互联网
Google AD

IT公司速查手册·版权所有
'---------新闻统计