JNI(Java Native Interface)
Java 调用c/c++,c/c++调用java的一套API
步骤如下:
1,编写native方法,
2,javah命令,生成.h文件
javah 完整类名
3,复制.h 头文件到cpp工程中
4,复制jni.h和jni_md.h文件到CPP工程中,(可以从jdk中复制)
5,实现.h头文件中生声明的函数
6,生成动态库,供java使用
C的函数名称:Java_完整类名_函数名
每个native函数,都至少有两个参数,(JNIEnv *,jclass活者(jobject))
1)当native方法为静态方法时:
jclass 代表native方法所属的类的class对象(JniTest.class)
2)当native方法为非静态方法时:
jclass 代表native方法所属对象
基本数据
Java基本数据类型与JNI数据类型的映射关系
Java类型->JNI类型->C类型
boolean jboolean
byte jbyte
char jchar
short jshort
int jint
long jlong
float jfloat
double jdouble
void void
引用类型(对象)
String jstring
object jobject
数据,基本类型的数组
byte[] jByteArray
对象数组
object[] (String[]) jobjectArray
JNIEnv
在C中:
结构体指针,代表Java运行环境,调用Java中的代码,env 在C中是二级指针
在C++中:
是一个结构体的别名,env 是一个一级指针
1,为什么需要传入JNIEnv,函数的执行过程中需要JNIEnv
2,C++为什么没有传入,因为通过this可以获取到env。
3,C++只是对C的那一套进行了封装,给一个变量赋值为指针,这个变量是二级指针。
// JNIEnv结构体的指针别名
typedef struct JNINativeInterface_ * JNIEnv;
// 结构体 (*NewStringUTF)是一个函数指针表示指向函数的指针
struct JNINativeInterface_{
char * (*NewStringUTF)(JNIEnv*,char*);
};
//函数实现
char * NewStringUTF(JNIEnv * env,char * str){
// 在NewStringUTF执行过程中,仍然需要JNIEnv
return str;
};
int main(){
// 实例化结构体
struct JNINativeInterface_ struct_env;
struct_env.NewStringUTF = NewStringUTF;
// 结构体指针
JNIEnv e = & struct_env;
//结构体的二级指针
JNIEnv *env = &e;
// 通过二级指针调用函数
char * str = (*env)->NewStringUTF(env,"abc");
printf("%s\n",str);
return 1;
}