目前java与dll交互的技术主要有3种:jni,jawin和jacob。Jni(Java Native Interface)是sun提供的java与系统中的原生方法交互的技术(在windows\linux系统中,实现java与native method互调)。目前只能由c/c++实现。后两个都是sourceforge上的开源项目,同时也都是基于jni技术的windows系统上的一个应用库。Jacob(Java-Com Bridge)提供了java程序调用microsoft的com对象中的方法的能力。而除了com对象外,jawin(Java/Win32 integration project)还可以win32-dll动态链接库中的方法。就功能而言:jni >> jawin>jacob。
java本地开发接口,JNI是一个协议,这个协议用来沟通java代码和外部的本地代码(c/c++).通过这个协议,java代码就可以调用外部的c/c++,代码外部的c/c++代码也可以调用java代码。JNI开发用途:驱动开发 (wifi-hotspot) 2.3无线热点共享,Native code效率高,数学运算,实时渲染的游戏上,音视频处理(极品飞车,opengl,ffmpeg),复用代码(文件压缩,人脸识别…)等。
JNI的使用
JNI 的使用有两种方法。第一种方法首先要在Java 层声明要调用的本地方法,需要加上关键字native,例如:private native void sayhello();在Java 层不需要实现这个方法。然后需要将Java 代码编译成字节码,需要使用jdk 提供的Java 编译器javac。
Jni程序开发示例1:
1 创建JAVA调用DLL代码
在eclipse项目中新建一个TestHello.java,输入以下内容:
public class TestHello {
static {
System.loadLibrary("TestHello");
}
public static native void hello(String msg);
public static void main(String[] args) {
hello("Hello,Kimm!");
}
}
编译生成TestHello.class文件。
2 用javah解释成C++版的头文件
在命令行下使用javah TestHello命令,生成TestHello.h头文件(就是jni代理stub的接口),内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestHello */
#ifndef _Included_TestHello
#define _Included_TestHello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: TestHello
* Method: hello
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_TestHello_hello
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif
其中,JNIEXPORT和JNICALL 是用于导出函数的、依赖于编译器的指示符。返回类型是映射到Java类型的C/C++类型。除了Java声明中的一般参数以外,所有这些函数的参数表中都有一个指向JNIEnv和jobject 的指针。指向JNIEnv 的指针实际上是一个指向函数指针表的指针。这些函数提供各种用来在C和C++中操作Java数据的能力。jobject 参数引用当前对象。因此,如果C 或C++代码需要引用Java函数,则这个jobject 充当引用或指针,返回调用的Java 对象。函数名本身是由前缀“Java_”加全限定类名,再加下划线和方法名构成的。
3 实现C++版的动态库
在VC6中新建一个项目TestHello, 项目类型为Win32 Dynamic-Link Library。点击OK。
在弹出的窗口中选择A simple DLL project,点击Finish。
打开项目所在的文件目录,将步骤2中生成的TestHello.h文件复制到此目录。点击左边中间的FileView,切换到文件浏览模式。在Header Files上点击右键,选择Add Files to Folder…。
选择TestHello.h文件,点击OK。
打开StdAfx.h文件,再最后面添加:
#include <jni.h>
#include "TestHello.h"
打开TestHello.cpp文件,在最后面添加一段代码:
JNIEXPORT void JNICALL Java_TestHello_hello(JNIEnv * env, jclass obj, jstring jMsg)
{
const char *strMsgPtr = env->GetStringUTFChars( jMsg , 0);
MessageBox( 0, strMsgPtr,"Message box from VC++ ", 0 );
env->ReleaseStringUTFChars( jMsg, strMsgPtr);
}
在VC的菜单上选择Tools-Options…,打开选项对话框。在Directories文件夹,添加上jdk所在文件夹下的include和include\win32文件夹。
点击VC上的菜单项Build-Build All,生成TestHello.dll。
4、 将VC项目Debug文件夹中的TestHello.dll复制到TestHello.class所在的文件夹下。
5、 在命令行下输入java TestHello,弹出MessageBox对话框。调用win32 api成功。
Jni程序开发示例2:
写个MyJni.java如下:
package kg.tom;
public class MyJni {
//使用JNI的关键字native
//这个关键字决定我们那些方法能在我们的C文件中使用
//只须声明,不必实现
public native void display();
public native double sum(double x,double y);
//这个是到时候调用我们写好的C文件
//现在用不上
static {
System.loadLibrary("sum");
}
public static void main(String[] args) {
//到时候测试用方法现在用不上
new MyJni().display();
System.out.println(new MyJni().sum(2.0, 3.0));
}
}
1 执行javah
假设MyJni在kg/tom/目录下,执行javah kg.tom.MyJni,生成头文件kg_tom_MyJni.h。
Windows下编译库
建立win32动态库工程sum,加入kg_tom_MyJni.h,引入“jni.h”跟“jni_md.h”路径。
将"test.dll"考入java源文件的目录,执行javac kg/tom/MyJni.java,执行java kg/tom/MyJni,即得出结果Hello World tom!!5.0。
java本地开发接口,JNI是一个协议,这个协议用来沟通java代码和外部的本地代码(c/c++).通过这个协议,java代码就可以调用外部的c/c++,代码外部的c/c++代码也可以调用java代码。JNI开发用途:驱动开发 (wifi-hotspot) 2.3无线热点共享,Native code效率高,数学运算,实时渲染的游戏上,音视频处理(极品飞车,opengl,ffmpeg),复用代码(文件压缩,人脸识别…)等。
JNI的使用
JNI 的使用有两种方法。第一种方法首先要在Java 层声明要调用的本地方法,需要加上关键字native,例如:private native void sayhello();在Java 层不需要实现这个方法。然后需要将Java 代码编译成字节码,需要使用jdk 提供的Java 编译器javac。
Jni程序开发示例1:
1 创建JAVA调用DLL代码
在eclipse项目中新建一个TestHello.java,输入以下内容:
public class TestHello {
static {
System.loadLibrary("TestHello");
}
public static native void hello(String msg);
public static void main(String[] args) {
hello("Hello,Kimm!");
}
}
编译生成TestHello.class文件。
2 用javah解释成C++版的头文件
在命令行下使用javah TestHello命令,生成TestHello.h头文件(就是jni代理stub的接口),内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestHello */
#ifndef _Included_TestHello
#define _Included_TestHello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: TestHello
* Method: hello
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_TestHello_hello
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif
其中,JNIEXPORT和JNICALL 是用于导出函数的、依赖于编译器的指示符。返回类型是映射到Java类型的C/C++类型。除了Java声明中的一般参数以外,所有这些函数的参数表中都有一个指向JNIEnv和jobject 的指针。指向JNIEnv 的指针实际上是一个指向函数指针表的指针。这些函数提供各种用来在C和C++中操作Java数据的能力。jobject 参数引用当前对象。因此,如果C 或C++代码需要引用Java函数,则这个jobject 充当引用或指针,返回调用的Java 对象。函数名本身是由前缀“Java_”加全限定类名,再加下划线和方法名构成的。
3 实现C++版的动态库
在VC6中新建一个项目TestHello, 项目类型为Win32 Dynamic-Link Library。点击OK。
在弹出的窗口中选择A simple DLL project,点击Finish。
打开项目所在的文件目录,将步骤2中生成的TestHello.h文件复制到此目录。点击左边中间的FileView,切换到文件浏览模式。在Header Files上点击右键,选择Add Files to Folder…。
选择TestHello.h文件,点击OK。
打开StdAfx.h文件,再最后面添加:
#include <jni.h>
#include "TestHello.h"
打开TestHello.cpp文件,在最后面添加一段代码:
JNIEXPORT void JNICALL Java_TestHello_hello(JNIEnv * env, jclass obj, jstring jMsg)
{
const char *strMsgPtr = env->GetStringUTFChars( jMsg , 0);
MessageBox( 0, strMsgPtr,"Message box from VC++ ", 0 );
env->ReleaseStringUTFChars( jMsg, strMsgPtr);
}
在VC的菜单上选择Tools-Options…,打开选项对话框。在Directories文件夹,添加上jdk所在文件夹下的include和include\win32文件夹。
点击VC上的菜单项Build-Build All,生成TestHello.dll。
4、 将VC项目Debug文件夹中的TestHello.dll复制到TestHello.class所在的文件夹下。
5、 在命令行下输入java TestHello,弹出MessageBox对话框。调用win32 api成功。
Jni程序开发示例2:
写个MyJni.java如下:
package kg.tom;
public class MyJni {
//使用JNI的关键字native
//这个关键字决定我们那些方法能在我们的C文件中使用
//只须声明,不必实现
public native void display();
public native double sum(double x,double y);
//这个是到时候调用我们写好的C文件
//现在用不上
static {
System.loadLibrary("sum");
}
public static void main(String[] args) {
//到时候测试用方法现在用不上
new MyJni().display();
System.out.println(new MyJni().sum(2.0, 3.0));
}
}
1 执行javah
假设MyJni在kg/tom/目录下,执行javah kg.tom.MyJni,生成头文件kg_tom_MyJni.h。
Windows下编译库
建立win32动态库工程sum,加入kg_tom_MyJni.h,引入“jni.h”跟“jni_md.h”路径。
将"test.dll"考入java源文件的目录,执行javac kg/tom/MyJni.java,执行java kg/tom/MyJni,即得出结果Hello World tom!!5.0。