[Java] 调用Native Windows API的几种方法JNI, JNA, JNative

博客首页 » Java 调用Native Windows API的几种方法JNI, JNA, JNative

发布于 16 Dec 2015 09:37
标签 blog
Java的最好特性就是平台无关,可是我们有时需要平台的强大功能。本文介绍调用Native Windows API的几种方法JNI, JNA, JNative,BridJ。

参考资料:
http://blog.csdn.net/ranmudaofa/article/details/9798779
http://stackoverflow.com/questions/1556421/use-jni-instead-of-jna-to-call-native-code

总结:
JNI - 需要javah,繁琐
JNA - 简单,但是需要处理C-Java
JNative - 简单,三方
BirdJ - 简单,支持C++

JNA

JNA Demo

引入和下载JNA库

为了使用JNA,需要引入JNA库
Maven POM

    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna</artifactId>
        <version>4.2.1</version>
    </dependency>
    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>platform</artifactId>
        <version>3.5.2</version>
    </dependency>
API定义方法

使用JNA需要定义继承自StdCallLibrary, WinUser的借口,如这次使用的User32,
还需要一个 Native.loadLibrary的实例,一般直接定义到我们刚才定义的借口里,叫INSTANCE,
然后就可以调用了,注意匹配类型和常量。

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;
 
public class JnaDemo {
 
    final static int WM_KEYDOWN = 0x0100;
    final static int WM_KEYUP = 0x0101;
    final static int WM_CHAR = 0x0102;
    final static int VK_A = 0x61;
    final static int SW_RESTORE = 0x09;
 
    public interface User32 extends StdCallLibrary, WinUser {
 
        User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class, W32APIOptions.DEFAULT_OPTIONS);
 
        public abstract HWND FindWindow(String paramString1, String paramString2);
        public abstract HWND FindWindowEx(HWND hwndParent, HWND hwndChildAfter, String lpszClass, String lpszWindow);
        public abstract void PostMessage(HWND hWnd, int msg, WPARAM wParam, LPARAM lParam);
        public abstract void ShowWindow(HWND hWnd, int nCmdShow);
        public abstract LRESULT SendMessage(HWND hWnd, int msg, WPARAM wParam, LPARAM lParam);
        public abstract void SetForegroundWindow(HWND hWnd);
        public abstract void SetFocus(HWND hWnd);
 
    }
 
    public static void main(String[] args) {
 
        HWND parent = User32.INSTANCE.FindWindow("Notepad", null);
        System.out.println("parent " + (parent == null ? parent : parent.getPointer()));
 
        if (parent != null) {
 
            HWND child = User32.INSTANCE.FindWindowEx(parent, null, "Edit", null);
            System.out.println("child " + (child == null ? child : child.getPointer()));
 
            User32.INSTANCE.ShowWindow(parent, SW_RESTORE);
            User32.INSTANCE.SetForegroundWindow(parent);
 
            if (child != null) {
                User32.INSTANCE.SetFocus(child);
 
                WPARAM wPARAM = new WPARAM(VK_A);
                LPARAM lPARAM = new LPARAM(0);
 
                //User32.INSTANCE.PostMessage(child, WM_KEYDOWN, wPARAM, lPARAM);
                User32.INSTANCE.SendMessage(child, WM_KEYDOWN, wPARAM, lPARAM);
                User32.INSTANCE.SendMessage(child, WM_CHAR, wPARAM, lPARAM);
                User32.INSTANCE.SendMessage(child, WM_KEYUP, wPARAM, lPARAM);
            }
        }
    }
}
使用定义好的platform.jar简化写法

此外,我们还可以引入platform.jar包,这里有大多数API的声明,可以直接使用。

package net.sf.orassist.jnademo;
 
import com.sun.jna.Native;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.win32.W32APIOptions;
 
import static net.sf.orassist.jnademo.MyUser32.*;
 
interface MyUser32 extends User32 {
 
    MyUser32 INSTANCE = (MyUser32) Native.loadLibrary("user32", MyUser32.class, W32APIOptions.DEFAULT_OPTIONS);
 
    int VK_A = 0x61;
 
    public abstract HWND FindWindowEx(HWND hwndParent, HWND hwndChildAfter, String lpszClass, String lpszWindow);
    public abstract LRESULT SendMessage(HWND hWnd, int msg, WPARAM wParam, LPARAM lParam);
 
}
 
public class JnaDemo {
 
    public static void main(String[] args) {
 
        HWND parent = INSTANCE.FindWindow("Notepad", null);
        System.out.println("parent " + (parent == null ? parent : parent.getPointer()));
 
        if (parent != null) {
 
            HWND child = INSTANCE.FindWindowEx(parent, null, "Edit", null);
            System.out.println("child " + (child == null ? child : child.getPointer()));
 
            INSTANCE.ShowWindow(parent, SW_RESTORE);
            INSTANCE.SetForegroundWindow(parent);
 
            if (child != null) {
                INSTANCE.SetFocus(child);
 
                WPARAM wPARAM = new WPARAM(VK_A);
                LPARAM lPARAM = new LPARAM(0);
 
                //MyUser32.INSTANCE.PostMessage(child, WM_KEYDOWN, wPARAM, lPARAM);
                INSTANCE.SendMessage(child, WM_KEYDOWN, wPARAM, lPARAM);
                INSTANCE.SendMessage(child, WM_CHAR, wPARAM, lPARAM);
                INSTANCE.SendMessage(child, WM_KEYUP, wPARAM, lPARAM);
            }
        }
    }
}

本页面的文字允许在知识共享 署名-相同方式共享 3.0协议和GNU自由文档许可证下修改和再使用,仅有一个特殊要求,请用链接方式注明文章引用出处及作者。请协助维护作者合法权益。


系列文章

文章列表

  • Java 调用Native Windows API的几种方法JNI, JNA, JNative

这篇文章对你有帮助吗,投个票吧?

rating: 0+x

留下你的评论

Add a New Comment