java中的native关键字
JNI是Java Native Interface
的 缩写。从Java 1.1开始,Java Native Interface (JNI)标准成为java平台的一部分,它允许Java代码
和其他语言写的代码进行交互
。JNI一开始是为了本地已编译语言,尤其是C和C++而设计 的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。
使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的,比如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少保证本地代码能工作在任何Java 虚拟机实现下。
JNI(Java Native Interface)的书写步骤
·编写带有native声明的方法的java类
·使用javac命令编译所编写的java类
·使用javah ?jni java类名生成扩展名为h的头文件
·使用C/C++(或者其他编程想语言)实现本地方法
·将C/C++编写的文件生成动态连接库=
目前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,其大致的结构如下图:
JNI实例
下列是所有操作都是在目录: D:\JNI 下进行的,这样做的好处是便于控制。还有另外一个要求是我们的java类不含包名,当前我只测试成功不含包名的类型。
编写带有native声明的方法的java类:HelloWorld.java
public class HelloWorld {
public native void displayHelloWorld();// java native方法申明
static {
System.loadLibrary("HelloWorldImpl");// 装入动态链接库,"HelloWorldImpl"是要装入的动态链接库名称。
}
public static void main(String[] args) {
// TODO Auto-generated method stub
HelloWorld helloWorld = new HelloWorld();
helloWorld.displayHelloWorld();
}
}
使用javac命令编译所编写的java类
d:\JNI>javac HelloWorld.java
执行完上述命令以后生成 D:\JNI\HelloWorld.class
文件
使用javah -jni java类名生成扩展名为h的头文件
d:\JNI>javah -jni HelloWorld
假如执行javah指令出现错误时参考一下解决方案:
java开发中如果使用到JNI,则难免需要使用javah来生成C++或C的头文件信息,下面小编就直接说说javah的命令:
第一种:直接cd到当前程序的target/class目录下(maven项目,如果是普通项目则到bin目录下) 然后使用:javah com.yongcheng.liuyang.utils.TestJni,其中javah后面的是需要生成头文件类的全路径(包名+类名),当然生成的.h文件位于当前class的目录下。
第二种:直接在运行中cmd到dos窗口,使用如下命令:javah -classpath D:\QulityBg\SpringMVCTest\target\classes com.yongcheng.liuyang.utils.TestJni
其中-classpath后跟当前程序在磁盘上的位置,该位置只写到class路径或者bin路径,后面是需要生成头文件类的全路径。
好了以上就是javah的简单使用,当然也可以增加一些参数,比如常见的-d,即就是将生成的头文件存放的位置,具体可直接使用javah -h查看响应的参数以及含义。
执行完上述命令以后生成 D:\JNI\HelloWorld.h文件,该文件内容如下:/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: displayHelloWorld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
这里我们可以这样理解:这个h文件相当于我们在java里面的接口,这里声明了一个 Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致
使用C/C++实现本地方法
创建HelloWorldImpl.cpp
,代码如下所示:
#include "HelloWorld.h"
#include <stdio.h>
#include <jni.h>
/*
* Class: HelloWorld
* Method: displayHelloWorld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
(JNIEnv *, jobject)
{
printf("Hello World!\n");
return;
}
将C/C++编写的文件生成动态连接库
将 F:\java\jdk\jdk1.8.0_101\include\jni.h和 F:\java\jdk\jdk1.8.0_101\include\win32\jni_md.h这两个文件拷贝到 D:\JNI\目录下。与HelloWorldImpl.cpp同目录,目录结构如下图所示:
执行 cl/LD D:\JNI\HelloWorldImpl.cpp 得到HelloWorldImpl.dll文件
我使用的是visual studio 2010,要使用其中的cl命令,必须打开visual studio 命令行,如下图所示:
然后再命令行中输入如下命令
cl/LD D:\JNI\HelloWorldImpl.cpp
具体如下图所示:
执行完上述命令以后,我们在C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC可以看到生成的四个文件,分别是:
HelloWorldImpl.dll
HelloWorldImpl.exp
HelloWorldImpl.lib
HelloWorldImpl.obj
将其中的HelloWorldImpl.dll拷贝到 D:\JNI\目录下。
执行class得到结果
在cmd中运行:
d:\JNI>java HelloWorld