今天记录一下学习Android中JNI的过程,JNI全称java native interface,负责Java和native之间的函数互相调用,本文记录下JNI静态注册的学习过程。
第一步、首先新建一个测试目录
mkdir ~/jnitest
cd ~/jnitest
第二步、新建一个java文件
jnitest.java,里面只有一个class,声明一下加载库和native的函数,然后在本类方法中调用native函数即可:
class jnitest
{
static
{
System.loadLibrary("jnitest_nativelibrary");
}
public native void jni_nativefunction();
public void jni_javafunction()
{
jni_nativefunction();
}
public static void main(String[] args) {
jnitest class_interface = new jnitest();
class_interface.jni_javafunction();
}
}
第三步、编译Java文件,生成.class文件:
javac jnitest.java
第四步、采用javah生成C++的头文件:
javah jnitest
第五步、查看生成的.h文件,写.cpp文件:
先是查看生成的头文件,cat jnitest.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jnitest */
#ifndef _Included_jnitest
#define _Included_jnitest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jnitest
* Method: jni_nativefunction
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_jnitest_jni_1nativefunction
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
在这个头文件中有一个函数的声明,这个声明就是我们需要在.cpp文件中实现的接口,也就是java类中通过库来访问的函数,接下来就是编写jninative.cpp文件:
#include "jnitest.h"
JNIEXPORT void JNICALL Java_jnitest_jni_1nativefunction
(JNIEnv *, jobject)
{
printf(" hello world from jninative.cpp\n");
}
第六步、编写Makefile文件
jnitest_nativelibrary.so:jninative.o
g++ -Wall -rdynamic -shared -o libjnitest_nativelibrary.so jninative.o
jninative.o:jninative.cpp
g++ -Wall -fPIC -c jninative.cpp -l ./ -I /usr/lib/jvm/sun-java6-jdk/include/ -I /usr/lib/jvm/sun-java6-jdk/include/linux/
clean:
rm -rf *.o *.so
第七步、编译cpp文件并运行
编译
make
拷贝库文件到/lib/下
cp libjnitest_nativelibrary.so /lib
运行
#:~/myjnitest# java jnitest
hello world from jninative.cpp
到此为止,jni的静态注册已经完毕,实现了java代码对c++代码的调用,接下来继续研究jni的动态注册。