JNI编程基础
JNI基础概念
操作实例:
Java Native Interface Java本地调用 主要是为了和C/C++交互
JNI操作函数
JNI异常
如果出现java.lang.UnsatisfiedLinkError的异常,解决方法如下:
1.java -Djava.library.path
2.export LD_LIBRARY_PATH
操作实例:
1.编写 TestJni.java
public class TestJin{
//定义的一个native方法,并加载动态库
public native void print(String str);
static{
System.loadLibrary("MyJni");
}
public static void main(String[] args){
new TestJin().print("hello jni");
}
}
2.编译 javac TestJin.java
3.生成头文件 javah -jni TestJni
4.重命名 mv TestJni.h MyJni.h
5.添加修改代码 MyJni.h
#include<MyJni.h>
#include<stdio.h>
/* Header for class TestJni*/
#ifndef _Included_TestJni
#define _Included_TestJni
#ifdef __cplusplus
extern "C"{
#endif
JNIEXPORT void JNICALL Java_TestJni_print
(JNIEnv *env, jobject obj, jstring str){
jchar *s =(jchar *)(*env) ->GetStringUTFChars(env,str,NULL);
printf("content is %s\n",(char *)s);
(*env)->ReleaseStringUTFChars(env,str,(const char*)s);
}
#ifdef __cplusplus
}
#endif
#endif
- /*
- 1.JNIEnv是JNI的核心数据,指向JNIEnv结构的指针
- 2.jobject的意义取决于该方法是否是静态还是实例方法。当本地方法作为一个实例方法时,第二个参数相当于对象本身,即this.当本地方法作为一个静态方法时,指向所在类。
- 3.jni.h文件必须被包含,该文件定义了JNI所有的函数声明和数据类型。
- 4.JNIEXPORT和JNICALL是可忽略的JNI关键字,其实是一些宏,想了解的可以找jni_md.h文件查看。我们目前使用的jni.h定义他们为空。
- */
6.执行命令生成 libMyJni.so文件
gcc -fPIC -shared -o libMyJni.so MyJni -I. -I/home/dir -I/%JAVA_HOME%
1)JNI
java code 与 c/c++进行交互
2)JNI编程流程
a. 编写一个.java
b.javac *.java
c.javah -jni className -> *.h
d.在.c/.cpp文件实现这个native方法
e.创建一个.so/.dll
3)数据类型
char -> jchar boolean -> jboolean ...
4)出现java.lang.UnsatifiedLinkedError的异常
java -Djava.library.path
export LD_LIBRARY_PATH
5)注意事项
a.不要直接使用从Java里面传递过来的对象,基本数据类型,要用过环境指针转换 (*env) ->
b.一旦不使用某个对象或变量,要去释放内存release
c.不要在native code里面去申请内存
JNI签名
可以通过javap -s 查看类的签名
JNI签名类型