在java中使用JNI来编程

    今天在看代码的时候,发现文件中使用了native修饰的方法,本来想跟踪进去看一看的,发现并不可以,通过查资料才发现,使用native修饰的方法是调用本地方法,也就是本地使用C/C++编写的库函数,今天就来总结一下我的一些学习心得和在实践过程中遇到的问题。


    native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。总而言之:

  1. native 是用做java 和其他语言(如c++)进行协作时使用的,也就是native 后的函数的实现不是用java写的。
  2.  既然都不是java,那就别管它的源代码了,我们只需要知道这个方法已经被实现即可。
  3. native的意思就是通知操作系统, 这个函数你必须给我实现,因为我要使用。 所以native关键字的函数都是操作系统实现的, java只能调用。
  4. java是跨平台的语言,既然是跨了平台,所付出的代价就是牺牲一些对底层的控制,而java要实现对底层的控制,就需要一些其他语言的帮助,这个就是native的作用了

native方法是通过java中的JNI实现的。JNI是Java Native Interface的 缩写。从Java 1.1开始,Java Native Interface (JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计 的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的,比如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少保证本地代码能工作在任何Java 虚拟机实现下。

JNI的开发步骤:

    1.编写带有native声明的方法的java类,生成*.java文件

    2.使用javac命令编译所编写的java类,生成.class文件

    3.使用javah -jni java类名(第一步生成的) 生成扩展名为h的头文件,也就生成.h文件

    4.使用C/C++(或其他编程语言)实现本地方法,创建.h文件的实现,也就是创建.cpp文件实现.h文件中的方法

    5.将C/C++编写的文件生成动态链接库,即生成dll文件


JNI开发实例:

1.编写带有native声明的方法的java类

<span style="font-size:18px;">public class HelloWorld{

    public native void displayHelloWorld();

    static{
        System.loadLibrary("HelloWorldImpl");  
       //装入动态链接库,“HelloWorldIdImpl”是要装入的动态链接库名称

    }

    public static void main(String[] args){
           HelloWorld helloworld=new HelloWorld();

           helloworld.displayHelloWorld();
    }

}</span>


2.生成.class文件和.h文件

    首先,打开命令窗口,开始->运行->cmd,切换到你的java文件所在目录

然后运行命令:javac HelloWorld.java,在本文件夹下生成.class文件

然后继续输入:javah -jni HelloWorld,生成HelloWorld.h文件



3.打开HelloWorld.h文件,内容如下:

<span style="font-size:18px;">/* 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</span>

可以看到我们定义的displayHelloWorld,在此处生成了方法Java_HelloWorld_displayHelloWorld(JNIEnv *,jobject)

4.新建一个.cpp文件实现上面的方法(我使用的是Visual Studio 2010版本)

注意:新建的cpp文件名称要和我们在第一步中System.loadLibrary("HelloWorldImpl")设置的名称一致

新建过程如下:点击新建->项目







编写HelloWorldImpl.cpp文件:

#include"HelloWorld.h"
#include<stdio.h>
#include"jni.h"

JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *, jobject){

     printf("Hello World,this method written by C++\n");
	 return ;
} 

生成动态链接库:

  A.将HelloWorldImpl.cpp文件拷贝到java文件同一级目录下

  B.然后找到你的jdk安装目录\include文件夹,我的安装路径是:D:\program files(X86)\Java\jdk\include

  C.将D:\program files(X86)\Java\jdk\include\jni.h;D:\program files(X86)\Java\jdk\include\win32\jawt_md.h和                 jni_md.h拷贝到你的Visual Studio\VC\include文件夹下

     我的路径是:D:\program files(X86)\Visual Studio2010\Micro Visual Studio\VC\include

   D.打开visual Studio 命令提示


打开之后,运行以下命令:


可以看到我们编译成功啦!打开我们的Visual Studio/VC文件夹,可以看到我们生成的文件



提示:这一步中可能会出现以下错误提示:


原因分析:

没有把jni.h文件拷贝到Visual Studio\include文件,拷贝过来之后,就可以正常显示了。


然后将HelloWorldImpl.dll文件拷贝到原来创建java文件的文件夹下,然后去命令行界面运行文件HelloWorld.class文件


运行结果如上所示。

over~~~








猜你喜欢

转载自blog.csdn.net/qq_31490071/article/details/51283055