JNI (三)
来源:互联网 发布:美国eia数据公布 编辑:程序博客网 时间:2024/05/16 08:18
JNI (三) 接上一次,大家都知道了jni是sun提供的java与系统中的原生方法交互的技术(在windows\linux系统中,实现java与native method互调)。目前只能由c/c++实现。但前两次我们都自己编写的dll文件,然后再用java程序去调用。那假设要在Java中调用已有的动态库,如 Windows 的 user32.dll 的方法 MessageBox,该如何操作呢?
(1)在Java 类中声明一个 native 方法,然后用 javah 命令生成JNI样式的头文件.
(2 ) 在vc++中 再自己实现头文件中声明的方法,在实现方法中装载动态库 user32.dll,调用 MessageBoxA 方法,实现功能.
(3) 再把自己写的这部分 C/C++ 代码封装成一个动态库,如Sample.dll,最后在 java 中装载 Sample.dll,然后执行其中所声明的本地方法。
(1)在Java 类中声明一个 native 方法,然后用 javah 命令生成JNI样式的头文件.
(2 ) 在vc++中 再自己实现头文件中声明的方法,在实现方法中装载动态库 user32.dll,调用 MessageBoxA 方法,实现功能.
(3) 再把自己写的这部分 C/C++ 代码封装成一个动态库,如Sample.dll,最后在 java 中装载 Sample.dll,然后执行其中所声明的本地方法。
可见,用老实的JNI方式,我们在调用一个已知动态库的时候还需要额外生成一个符合JNI规则的动态库作为桥梁,显得有点多余了.
那怎么办呢?
在sourceforge上的有几个开源项目,jacob, jawin, jnative, 它们都是基于jni技术的应用库. 前两个都是应用于windows平台上的,而后一个可以应用于windows,linux两个平台.
Jacob(Java-Com Bridge)提供了java程序调用microsoft的com对象中的方法的能力。而除了com对象外,jawin(Java/Win32 integration project)还可以win32-dll动态链接库中的方法。
就功能而言:jni >> jawin>jacob,其大致的结构如下图:
在windows系统上,一般可执行的应用程序都是基于native的PE结构,windows上的jvm也是基于native结构实现的。Java应用体系都是构建于jvm之上。
Jni对于应用本身来说,可以看做一个代理模式。对于开发者来说,需要使用c/c++来实现一个代理程序(jni程序)来实际操作目标原生函数,java程序中则是jvm通过加载并调用此jni程序来间接地调用目标原生函数。
下面我们用jnative库来实现一个基于windows平台的本地方法调用的案例:
(1)当然是下载jnative的jar包了. 地址: http://sourceforge.net/projects/jnative/?source=dlp
在这个jar包中,你可以找到 JNativeCpp.dll (用于windows平台动态链接库) libJNativeCpp.s(用于linux平台动态链接库)两个文件.
(2) 这次我用eclipse来进行开发。 新建好项目后,将jnative.jar包导入到项目的构建路径下.
首先我们看一下MessageBox函数的签名: (其它的user32函数请参: http://wenku.baidu.com/view/321f9e621ed9ad51f01df22b.html)
返回值 MessageBox(父窗体id, 内容, 标题, 按钮特征号);
创建一个Test.java的类, 在其中加入一个messageBox方法来调用messagBox函数,将给这个函数传参, 接着写入代码:
public static final int messageBox(int parentHandle, String message, String caption, int buttons) throws NativeException,IllegalAccessException {
JNative n = null;
try {
n = new JNative("User32.dll", "MessageBoxA"); // 常量DLL_NAME的值为User32.dll
// 构造JNative时完成装载User32.dll,并且定位MessageBoxA方法
n.setRetVal(Type.INT); // 指定返回参数的类型
int i = 0;
n.setParameter(i++, Type.INT, "" + parentHandle); //设置父窗体id,
n.setParameter(i++, Type.STRING, message); //内容
n.setParameter(i++, Type.STRING, caption); //标题
n.setParameter(i++, Type.INT, "" + buttons); // 指定位置上的参数类型和值 //按钮
n.invoke(); // 调用方法
return Integer.parseInt(n.getRetVal());
} finally {
if (n != null)
n.dispose(); // 记得释放
}
}
public static void main(String[] args) throws NativeException, IllegalAccessException {
messageBox(0,"a","title",0);
}
运行后,ok.
linx下的做法也不样,只有调用的不是dll,而是 so库.
--------------------------------------------------------------------------------------------------------------------------------------------------------------
引申: 从这些案例的讲解中,大家应该想到,1. 整个jvm的运行都是调用了底层操作系统的动态链接库来完成操作的。 2. 我们用的swt, swing中的组件也是利用了jni技术调用了底层操作系统的api来实现的( 现在回过头来看上面图片最后输出的对话框是不是与swt的一样啊) 。 3. 通过这三期的讲解,终于打通了java与底层操作系统之间的通信, 以前VC++能做的,java也能做到了,大家想一想,有什么好的应用吗?........................期待你的实现.
那怎么办呢?
在sourceforge上的有几个开源项目,jacob, jawin, jnative, 它们都是基于jni技术的应用库. 前两个都是应用于windows平台上的,而后一个可以应用于windows,linux两个平台.
Jacob(Java-Com Bridge)提供了java程序调用microsoft的com对象中的方法的能力。而除了com对象外,jawin(Java/Win32 integration project)还可以win32-dll动态链接库中的方法。
就功能而言:jni >> jawin>jacob,其大致的结构如下图:
在windows系统上,一般可执行的应用程序都是基于native的PE结构,windows上的jvm也是基于native结构实现的。Java应用体系都是构建于jvm之上。
Jni对于应用本身来说,可以看做一个代理模式。对于开发者来说,需要使用c/c++来实现一个代理程序(jni程序)来实际操作目标原生函数,java程序中则是jvm通过加载并调用此jni程序来间接地调用目标原生函数。
下面我们用jnative库来实现一个基于windows平台的本地方法调用的案例:
(1)当然是下载jnative的jar包了. 地址: http://sourceforge.net/projects/jnative/?source=dlp
在这个jar包中,你可以找到 JNativeCpp.dll (用于windows平台动态链接库) libJNativeCpp.s(用于linux平台动态链接库)两个文件.
(2) 这次我用eclipse来进行开发。 新建好项目后,将jnative.jar包导入到项目的构建路径下.
首先我们看一下MessageBox函数的签名: (其它的user32函数请参: http://wenku.baidu.com/view/321f9e621ed9ad51f01df22b.html)
返回值 MessageBox(父窗体id, 内容, 标题, 按钮特征号);
创建一个Test.java的类, 在其中加入一个messageBox方法来调用messagBox函数,将给这个函数传参, 接着写入代码:
public static final int messageBox(int parentHandle, String message, String caption, int buttons) throws NativeException,IllegalAccessException {
JNative n = null;
try {
n = new JNative("User32.dll", "MessageBoxA"); // 常量DLL_NAME的值为User32.dll
// 构造JNative时完成装载User32.dll,并且定位MessageBoxA方法
n.setRetVal(Type.INT); // 指定返回参数的类型
int i = 0;
n.setParameter(i++, Type.INT, "" + parentHandle); //设置父窗体id,
n.setParameter(i++, Type.STRING, message); //内容
n.setParameter(i++, Type.STRING, caption); //标题
n.setParameter(i++, Type.INT, "" + buttons); // 指定位置上的参数类型和值 //按钮
n.invoke(); // 调用方法
return Integer.parseInt(n.getRetVal());
} finally {
if (n != null)
n.dispose(); // 记得释放
}
}
public static void main(String[] args) throws NativeException, IllegalAccessException {
messageBox(0,"a","title",0);
}
运行后,ok.
linx下的做法也不样,只有调用的不是dll,而是 so库.
--------------------------------------------------------------------------------------------------------------------------------------------------------------
引申: 从这些案例的讲解中,大家应该想到,1. 整个jvm的运行都是调用了底层操作系统的动态链接库来完成操作的。 2. 我们用的swt, swing中的组件也是利用了jni技术调用了底层操作系统的api来实现的( 现在回过头来看上面图片最后输出的对话框是不是与swt的一样啊) 。 3. 通过这三期的讲解,终于打通了java与底层操作系统之间的通信, 以前VC++能做的,java也能做到了,大家想一想,有什么好的应用吗?........................期待你的实现.
0 0
- jni(三)
- JNI (三)
- JNI接口函数<三>
- JNI接口函数<三>
- JNI接口函数<三>
- JNI学习笔记三
- JNI接口函数<三>
- android JNI 系列 三
- JNI (三)
- android JNI学习三
- 简介jni(三)
- JNI接口函数<三>
- JNI编程<三>
- android jni 编程 三
- JNI教程(三)
- 初学JNI知识(三)
- Java JNI学习(三)
- Android JNI调用(三)
- iOS开发------iOS 10 由于权限问题导致崩溃的那些坑
- Android WebView属性使用详解
- GitHub
- Linux(Ubuntu)下安装使用git
- 编写程序解决“百钱买百鸡”问题
- JNI (三)
- 验证“鬼谷猜想
- javaEE笔记三:JavaBean属性
- JNI (二)
- 编程求 1~10000 之间的所有“完全数”
- Android 集成支付宝SDK实现快捷支付--详解
- JNI技术(一)
- Mina学习(一):mina实现简单服务端与客户端
- HTML标签及效果大全