1. JNI的作用

JNI(Java Native Interface)提供了一种java与C/C++ 代码进行交互的方式,可以通过java方法调用C/C++ 的实现,和已有的C/C++ 库。

2. JNI使用方法

  • 首先在java类中声明native方法,与一般的函数声明类似,只是多了个native关键字
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package com.hello.jni;

    public class HelloJNI {
    static {
    System.loadLibrary("hello"); // Load native library at runtime
    // hello.dll (Windows) or libhello.so (Unixes)
    }

    // Declare a native method sayHello() that receives nothing and returns void
    private native void sayHello();

    // Test Driver
    public static void main(String[] args) {
    new HelloJNI().sayHello(); // invoke the native method
    }
    }
  • 使用javah命令生成相应的头文件(到elipse工程的bin目录下,打开命令行,注意不用带class后缀)

    javah com.hello.jni.HelloJNI
    这时在bin目录下会生成对应的头文件com_hello_jni_HelloJNI.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_hello_jni_HelloJNI */

    #ifndef _Included_com_hello_jni_HelloJNI
    #define _Included_com_hello_jni_HelloJNI
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
    * Class: com_hello_jni_HelloJNI
    * Method: sayHello
    * Signature: ()V
    */
    JNIEXPORT void JNICALL Java_com_hello_jni_HelloJNI_sayHello
    (JNIEnv *, jobject);

    #ifdef __cplusplus
    }
    #endif
    #endif
  • 然后就是要去实现之前声明的native方法,这里我们使用Visual Studio新建一个dll工程,
    这里需要将之前头文件所依赖的jni.h和jni_md.h所在的jdk目录添加到包含目录中,并将项目类型切换到与平台类型一致,否则会出现这样的不匹配错误
1
2
3
4
5
6
7
#include "com_hello_jni_HelloJNI.h"
#include <stdio.h>

JNIEXPORT void JNICALL Java_com_hello_jni_HelloJNI_sayHello(JNIEnv *, jobject)
{
printf("Hello World");
}
1
2
3
4
5
6
7
Exception in thread "main" java.lang.UnsatisfiedLinkError: D:\Workspace\AppProject\MyProjects\Debug\hello.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(Unknown Source)
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at com.hello.jni.HelloJNI.<clinit>(HelloJNI.java:5)
  • 将生成的dll文件的路径添加到环境变量中,这样JAVA类就可以调用dll中的C实现方法了

    Hello World