JNA使用手记一:
JNA初体验
相信关注这篇文章的朋友都有使用过jni的痛苦经历:
1,我是一个java开发人员,对C一点都不熟悉,jni让我用c写程序,开玩笑吧?
2,写c程序就罢了,hello world我还是写过,可你居然要我写个动态链接库!
3,难道我还得去配个c的编译环境,饶了我吧!
4,什么,原来我为调一个dll,又为这个dll包了一个dll,这不是坑爹吗?
所以有人说,JNI是java程序员的禁区,这是有原因的。
那么,传说中的JNA会为我们带来什么好处呢?据我的初步体验,现实的好处有2个
第一,不用为了调用一个动态库,自己还得再写意个动态库了,谁也不愿意当傻瓜,干体力活
第二,在java的类与c的结构体之间建立了映射关系,可以不再为异构的数据类型太过操心(其实还是有不少心要操)。
让我们来看看一个不是最简单,却行之有效的例子吧,我讨厌那种简单的毫无实用价值的例子。
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.win32.StdCallLibrary;
/**
* 测试JNA是否可以使用结构体调用dll
* User: xiaoming
* Email: xiaoming8484@gmail.com
* Date: 11-8-21
* Time: 下午2:13
*/
public class Kernel32Test {
/**
* 声明dll的接口
*/
public interface Kernel32 extends StdCallLibrary {
Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
void GetSystemTime(SYSTEMTIME result);
}
/**
* 定义与dll结构体对应的对象
*/
public static class SYSTEMTIME extends Structure {
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
}
/**
* 结构体的定义名称不一定要与c的保持一致,只需要数据结构一致即可
*/
public static class Input extends Structure {
public SYSTEMTIME systemtime;
}
public static void main(String args[]) {
Kernel32 lib = Kernel32.INSTANCE;
SYSTEMTIME time = new SYSTEMTIME();
Input input = new Input();
lib.GetSystemTime(time);
//lib.GetSystemTime(input);
System.out.println("Today's integer value is " + time.wDay);
// System.out.println("Today's integer value is " + input.systemtime.wDay);
}
}
没错,这就是全部,你是不是打算立即抛弃JNI了,其实你并没有逃离JNI的掌心,只是JNA帮你干了脏活而已,我们上班这么累,太需要有人帮我们干脏活了。
我们是艺术家,我们需要做有创造性的事情。
下一次见面将会给大家介绍JNA与C数据类型的对应关系,看我们面临哪些脏活,怎么样远离他们?