Java JNI 实例 Demo

何为JNI

JNI是Java Native Interface的英文缩写, 中文翻译为本地调用, 自从Java 1.1开始就成为了Java标准的一部分.

C/C++是系统级的编程语言, 可以用来开发任何和系统相关的程序和类库, 但是Java本身编写底层的应用比较难实现, 使用JNI可以调用现有的本地库, 极大地灵活了Java的开发.

C/C++的效率是目前最好的语言, 可以使用C/C++来实现一些实时性非常高的部分. C/C++和Java本身都是非常流行的编程语言, 一些大型软件中经常使用语言之间的混合编程.

Java调用C/C++大概有以下4个步骤

  1. 编写带有native方法的Java类, 使用javac工具(在Eclipse中直接build项目)编译Java类
  2. 使用javah来生成与native方法对应的头文件
  3. 在Visual Studio中导入并实现java的头文件,编译为动态链接库(windows下是.dll, linux下是.so)
  4. 在Java代码中引用动态链接库

步骤1-生成.class文件

在Eclipse中新建项目JavaTest,新建包com.hisign.jni,新建类HelloJNI。代码如下

其中有一句比较重要, 这句话加载了动态类库。在windows下加载的就是.dll, 在linux下加载的就是.so。

System.loadLibrary(“HelloJNI2”);

package com.hisign.jni;

public class HelloJNI {
    static{
        System.loadLibrary("HelloJNI2");//加载生成的HelloJNI2.dll
    }

    public HelloJNI() {
    }

    public native void sayHello(String name);
}

在Eclipse中build项目,在bin目录下会生成HelloJNI.class文件。
Java JNI 实例 Demo_第1张图片

步骤2-生成.h头文件

HelloJNI编写好之后,即可在DOS环境下将HelloJNI.java编译为HelloJNI.h头文件。进入 cmd 命令行,使用上一步生成的 .class 文件,利用 jdk 的 javah 命令生成 *.h 头文件。

javah命令
-classpath : 文件所在的根路径
-d : 输出 *.h 头文件的路径
-jni : 生成JNI样式的包头文件,可以理解成 *.class 文件的 包路径+类名

此处比较诡异的是,-classpath 必须得是.class 的包路径文件的上一级;-jni 必须是.class 文件的 包路径+类名,否则会报错。

这里写图片描述

步骤3-实现头文件方法,生成动态链接库

创建一个C++项目
Java JNI 实例 Demo_第2张图片
Java JNI 实例 Demo_第3张图片

使C++项目包含jdk 目录下的 jni.h 、 jni_md.h 以及之前生成的 com_hisign_jni_HelloJNI.h。这里有两种方法一种是把上述三个文件复制到C++项目的include文件夹(需要新建该文件夹)。然后
在C++项目的“包含目录”添加上include文件夹。第二种方法不用复制上述三个头文件,可以直接在C++项目的“包含目录”添加上上述三个头文件原本所在的文件夹。我偷懒使用了第二种方法,如下图
Java JNI 实例 Demo_第4张图片

实现头文件方法,新建类c++文件test.cpp,代码如下

#include 
#include 
#include 

JNIEXPORT void JNICALL Java_com_hisign_jni_HelloJNI_sayHello
  (JNIEnv* env, jobject obj, jstring name){

      const char* pname = env->GetStringUTFChars(name, NULL);
      std::cout << "Hello," << pname <<std::endl;
}

build项目在x64/Debug目录下生成HelloJNI2.dll文件。

C++项目中有两个坑,如果不熟悉VS的朋友容易掉坑里
第一坑是有关于你使用的操作系统位数,如果是32位那么默认是在32位平台编译,没有任何问题。如果是64位那么需要在配置管理器中把平台改为64位。(如果先做了上述添加头文件的操作再修改平台 需要在修改平台后再次添加头文件)
Java JNI 实例 Demo_第5张图片

第二坑是若是64位平台默认的配置类型不是DLL,导致编译失败。需要在项目属性页做如下修改,再次build。
Java JNI 实例 Demo_第6张图片

步骤4-在Java代码中引用动态链接库

在java项目下新建libs文件夹,把步骤3中生成的DLL文件复制进来。其实这个dll可以放在任何位置,但是需要配置Native library location, 配置位置在 工程属性->Java Build Path,配置Source标签或者Libraries标签下的Native library location都可以。
Java JNI 实例 Demo_第7张图片

在java项目中添加测试类,查看是否成功调用DLL中实现的方法。
Java JNI 实例 Demo_第8张图片

你可能感兴趣的:(java)