jni
简介
Java语言是基于C语言实现的,Java底层的很多API都是通过JNI(Java Native Interface)
来实现的。通过JNI
接口C/C++
和Java
可以互相调用(存在跨平台问题)。Java可以通过JNI调用来弥补语言自身的不足(代码安全性、内存操作等)。这个看似非常炫酷的特性其实自JDK1.1
开始就有了,但是我们不得不去考虑JNI调用带来的一系列的安全问题!
jni-定义native 方法
只需要添加一个native 关键字
1 |
|
jni-生成类头文件
已经编写好了java 文件,现在尝试将这个Java 文件编译成c 语言的头文件
javac -cp . org/example/JNILearn.java
javac -cp . org/example/JNILearn.java -h org/example
此时头文件就在 org/example
生成的文件特点
头文件的命名强制性
javah生成的头文件中的函数命名方式是有非常强制性的约束的,如
Java_com_anbai_sec_cmd_CommandExecution_exec
中Java_
是固定的前缀,而com_anbai_sec_cmd_CommandExecution
也就代表着Java的完整包名称:com.anbai.sec.cmd.CommandExecution
,_exec
自然是表示的方法名称了。(JNIEnv *, jclass, jstring)
表示分别是JNI环境变量对象
、java调用的类对象
、参数入参类型
。
Jni-基础数据类型
需要特别注意的是Java和JNI定义的类型是需要转换的,不能直接使用Java里的类型,也不能直接将JNI、C/C++的类型直接返回给Java。
参考如下类型对照表:
Java类型 | JNI类型 | C/C++类型 | 大小 |
---|---|---|---|
Boolean | Jblloean | unsigned char | 无符号8位 |
Byte | Jbyte | char | 有符号8位 |
Char | Jchar | unsigned short | 无符号16位 |
Short | Jshort | short | 有符号16位 |
Int | Jint | int | 有符号32位 |
Long | Jlong | long long | 有符号64位 |
Float | Jfloat | float | 32位 |
Double | Jdouble | double | 64位 |
jstring转char*:env->GetStringUTFChars(str, &jsCopy)
char*转jstring: env->NewStringUTF("Hello...")
字符串资源释放: env->ReleaseStringUTFChars(javaString, p);
其他知识点参考:jni中java与原生代码通信规则
编写逻辑
1 |
|
1 |
|
运行
1 |
|
COMMAND_CLASS_NAME 是最开始写的.java 的名字
COMMAND_CLASS_BYTES 是COMMAND_CLASS_NAME 对应的class 文件
一下的方法可以获取这个bytes
1 |
|