JNI初探
1. 简介
JNI = java native interface
允许java代码调用c/c++/asm语言编写的本地库.
JNI接口, 用native关键字, 来标识.
java.lang.Object 的相关native方法
java.lang.Object 的相关native方法
public final native Class<?> getClass();
public native int hashCode();
protected native Object clone() throws CloneNotSupportedException;
public final native void notify();
public final native void notifyAll();
public final native void wait(long timeout) throws InterruptedException;
2.Mac下的JniDemo
2.1 native接口(java定义)
public class JniDemo {
static {
/**
* 设置从当前目录查找本地库
*/
System.setProperty("java.library.path", ".");
/**
* 加载本地库
* 注意, 库名不能带平台相关的前缀和后缀
* 如, mac下, jnidemo = libjnidemo.dylib (动态库)
*/
System.loadLibrary("jnidemo");
}
public static void main(String[] args) {
System.out.println("before native add");
System.out.println(nativeAdd(1, 2));
System.out.println("after native add");
}
public static native int nativeAdd(int a, int b);
}
2.2 native接口(c定义)
- 编译及生成C头文件
liuxianqiang-mac:demo-java-jni liuxianqiang$ javac JniDemo.java
liuxianqiang-mac:demo-java-jni liuxianqiang$ javah JniDemo
liuxianqiang-mac:demo-java-jni liuxianqiang$ ll
-rw-r--r-- 1 liuxianqiang staff 641 11 27 22:14 JniDemo.java
-rw-r--r-- 1 liuxianqiang staff 750 11 27 22:15 JniDemo.class
-rw-r--r-- 1 liuxianqiang staff 403 11 27 22:15 JniDemo.h
- JniDemo.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JniDemo */
#ifndef _Included_JniDemo
#define _Included_JniDemo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JniDemo
* Method: nativeAdd
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_JniDemo_nativeAdd
(JNIEnv *, jclass, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
2.3 native接口(c实现)
#include "JniDemo.h"
JNIEXPORT jint JNICALL Java_JniDemo_nativeAdd
(JNIEnv *env, jclass jcls, jint a, jint b){
printf("inner native add \n");
return a + b;
}
2.4 编译C程序, 生成动态库
liuxianqiang-mac:demo-java-jni liuxianqiang$ gcc -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/include/ -I /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/include/darwin/ JniDemo.c -o libjnidemo.dylib
注意:
- -dynamiclib: 生成动态库
- -I: 导入头文件, 因为JniDemo.h依赖了, jni.h.
- -o: 指定生成的文件名
- libjnidemo.dylib: for mac, 其中lib是本地库前缀, dylib是本地库后缀, jnidemo是本地库的名称
2.5 运行
liuxianqiang-mac:demo-java-jni liuxianqiang$ ll
-rw-r--r--@ 1 liuxianqiang staff 638 11 27 22:37 JniDemo.java
-rw-r--r-- 1 liuxianqiang staff 750 11 27 22:37 JniDemo.class
-rw-r--r--@ 1 liuxianqiang staff 383 11 27 22:37 JniDemo.h
-rw-r--r--@ 1 liuxianqiang staff 319 11 27 22:41 JniDemo.c
-rwxr-xr-x 1 liuxianqiang staff 8400 11 27 22:42 libjnidemo.dylib*
liuxianqiang-mac:demo-java-jni liuxianqiang$ java JniDemo
before native add
inner native add
3
after native add
2.6 文件列表
文件 | 说明 |
---|---|
JniDemo.java | native接口, java定义 |
JniDemo.class | native接口, java定义, 编译后 |
JniDemo.h | native接口, c定义 |
JniDemo.c | native接口, c实现 |
libjnidemo.dylib | 编译JniDemo.h, JniDemo.c, 生成的本地库, 供JniDemo.class调用. |