., ++
,
,
.,
.++
..
.
JNI的开发流程
1.在java中声明native方法
public class JniTest {
static {
System.loadLibrary("jni-test");
}
public static void main(String args[]){
JniTest jniTest = new JniTest();
System.out.println(jniTest.get());
}
public native String get();
public native void set(String str);
}
2.编译java源文件的到class文件,然后通过javah命令导出JNI的头文件;
在当前目录下,会产生一个com_rgy_JniTest.h的头文件,它是用javah命令自动产生的
函数名的格式遵循如下规则:Java_包名_类名_方法名,如JniTest中的set,到这里就变成了JNIEXPORT void JNICALL Java_com_xx_JniTest_set(JNIEnv *,jobject,jstring)
JNIEXPORT JNICALL JNIEnv jobject都是JNI标准中所定义的类型或者宏
JNIEnv*:表示一个指向JNI环境的指针,可以通过它拉斯访问JNI提供的接口方法
jobject:表示java对象中的this
JNIEXPORT和JNICALL:它们是JNI中宏所定义的宏,可以在jni.h这个头文件中查找到
3.实现jni方法
jni方法是指java中所声明的native方法,可以选中c++ c来实现
1.在工程的主目录下创建一个子目录,名称随意,这里选择jni作为子目录的名称
2.将通过javah的生成的头文件com_xx_JniTest.h复制到目录下
3.创建test.cpp test.c两个文件
cpp:
#include "com_ryg_JniTest.h"
#include <stdio.h>
JNIEXPORT jstring JNICALL Java_com_ryg_JniTest_get(JNIEnv *env,jobject thiz){
printf("invoke get in c++\n");
return env->NewStringUTF("Hello from JNI!");
}
JNIEXPORT void JNICALL Java_com_ryg_JniTest_set(JNIEnv *env,jobject thiz,jstring string){
printf("invoke set in c++\n");
char* str=(char*)env->GetStringUTFChars(string,NULL);
printf("%s\n",str);
env->ReleaseStringUTFChars(string,str);
}
c:
#include "com_ryg_JniTest.h"
#include <stdio.h>
JNIEXPORT jstring JNICALL Java_com_ryg_JniTest_get(JNIEnv *env,jobject thiz){
printf("invoke get in c\n");
return (*env)->NewStringUTF(env,"Hello from JNI!");
}
JNIEXPORT void JNICALL Java_com_ryg_JniTest_set(JNIEnv *env,jobject thiz,jstring string){
printf("invoke set in c++\n");
char* str=(char*)env->GetStringUTFChars(string,NULL);
printf("%s\n",str);
(*env)->ReleaseStringUTFChars(env,string,str);
}
编译so库并在java中调用
so库的编译采用gcc,切换到jni目录中,
编译命令:
gcc -shared -I/usr/lib/jvm/java-7-openjdk-amd64/include-fPIC test.cpp -o libjni-test.so
gcc -shared -I/usr/lib/jvm/java-7-openjdk-amd64/include-fPIC test.c -o libjni-test.so
其中usr/lib/jvm/java-7-openjdk-amd64是本地的jdk的安装路径,libjni-test.so则是生成的so库的名字,在java中可以通过System.loadLibraray("jni-test")加载,其中so库中的lib和.so是不需要明确指出的;so库编译完成以后就可以在java程序中调用so库了
通过java指令来执行java程序,切换到主目录,执行如下命令:
java -Djava.library.path=jni com.ryg.JniTest,其中-Djava.library.path=jni指出了so库的路径