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