MelonTeam 移动终端前沿技术的探索者

JNI简介

2017-12-17
collinxu

JNI (Java Native Interface),也叫做java本地接口,可以允许java程序与其他语言编写的程序交互(本地交互/本地调用),从而可以扩展java程序功能,在一些场景下还可以用于提升性能。

JNI适用场景

1.为了使用底层主机平台的某些特性,而这些特性不能直接通过JAVA API访问,比如JDK中需要与操作系统交互的底层方法大多都是native的

2.为了访问一个已有的库,而这个库不是用JAVA编写的,比如需要在java程序中使用l5,cmlb,uls等这些C/C++组件就需要使用native接口
3.前面两个是被动使用JNI的场景,还有一种是为了提升java程序的性能,主动将某一些核心处理模块用更高效的语言(如C/C++等)编写,然后上级模块通过JNI去调用,比如百度开源的HCE(Hadoop C++ Extension),用C++重写了Hadoop的MapReduce组件以提升性能。

编写native接口步骤

以C/C++程序为例:

1. 在java程序中申明相应的方法为native

2. 编译生成.h

3. 在.c文件中实现该native方法

4. 将c程序编译生成动态链接库

5. 在java程序中通过System.loadLibrary()加载生成的动态链接库

编写native接口的小例子

1. 编写java程序

package test.ntv;

public class Test {
  public native void hello();

  static {
    System.loadLibrary("hello");
   }

  public static void main(String[] args) {
    new Test().hello();
  }
}

2. 编译java程序生成.class

~/java$   javac test/ntv/Test.java

3. 生成.h文件,本例中会生成名为test_ntv_Test.h的文件

~/java$   javah -jni test.ntv.Test

可以看下生成的test_ntv_Test.h的内容

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class test_ntv_Test */

#ifndef _Included_test_ntv_Test
#define _Included_test_ntv_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: test_ntv_Test
* Method: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_test_ntv_Test_hello
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

4. 编写.c文件,实现native接口

~/java$  cat test_ntv_Test.c

#include "test_ntv_Test.h"

JNIEXPORT void JNICALL Java_test_ntv_Test_hello
(JNIEnv * env, jobject obj) {
   printf("hello from c\n");
}

5. 编译c程序,生成动态链接库

~/java$  gcc -fPIC -shared test_ntv_Test.c -o libhello.so -I /usr/lib/jvm/java-6-openjdk-amd64/include/

注:由于生成的test_ntv_Test.h文件依赖jni.h文件,需要指定jni文件路径

6. 运行可执行程序test

~/java$  java -Djava.library.path=.   test.ntv.Test


上一篇 Lua 学习手记

说一说

目录