0%

学习JNI的使用

JNI(Java Native Interface)意为Java本地接口,虽然使用Java有段时间了,但对这个并不太了解。这个是基于网上老外的一篇文章的总结,环境是Mac OS

1
2
3
4
5
6
7
8
9
10
11
12
public class HelloWorldJNI {
static {
System.loadLibrary("native");
}

public static void main(String[] args) {
new HelloWorldJNI().sayHello();
}

// Declare a native method sayHello() that receives no arguments and returns void
private native void sayHello();
}

使用命令生成头文件

1
javac -h . HelloWorldJNI.java

生成如下的com_jasper_ji_maven_test_HelloWorldJNI.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_jasper_ji_maven_test_HelloWorldJNI */

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

#ifdef __cplusplus
}
#endif
#endif

我们再创建一个同名cpp文件

1
2
3
4
5
6
7
8
9
10
11
12
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "com_jasper_ji_maven_test_HelloWorldJNI.h"
#include <iostream>
/*
* Class: com_jasper_ji_maven_test_HelloWorldJNI
* Method: sayHello
* Signature: ()V
*/
void JNICALL Java_com_jasper_ji_maven_test_HelloWorldJNI_sayHello (JNIEnv *env, jobject obj)
{
std::cout << "Hello from C++ !!" << std::endl;
}

编译文件,生成com_jasper_ji_maven_test_HelloWorldJNI.o的文件

1
g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin com_jasper_ji_maven_test_HelloWorldJNI.cpp -o com_jasper_ji_maven_test_HelloWorldJNI.o

生成动态库

1
g++ -dynamiclib -o libnative.dylib com_jasper_ji_maven_test_HelloWorldJNI.o -lc

运行Java,这里需要注意的是-Djava.library.path路径我是把libnative.dylib这个文件路径放在com的根目录下的,也就是当前目录。

1
java -cp . -Djava.library.path=. com.jasper.ji.maven.test.HelloWorldJNI

总结

平时不太写C/C++的代码,所以有点生,不过之前对C的研究还是起了不少的帮助。JNI虽然提供了调用其他语言的功能,但是这是比较麻烦的,不同的平台需要编译对应的库。早前在做安卓的时候,倒是有简单的运行过NDK的例子,不过那会并没有专门研究下JNI。

参考

Guide to JNI (Java Native Interface)