C与C++中的JNIEnv。
2017-12-26 本文已影响124人
MrLuo
当我们通过javah生成头文件时。会有如下类似的代码:
JNIEXPORT jstring JNICALL Java_com_golf_getStringFromC
(JNIEnv *, jclass)
JNIEnv在C和C++里略有不同:
首页,看一下jni.h里面对它的定义:
#ifdef __cplusplus
typedef JNIEnv_ JNIEnv; //在C++中就是JNIEnv结构体的一个别名
#else
typedef const struct JNINativeInterface_ *JNIEnv; //在C中是JNINativeInterface的一个指针
#endif
// JNIEnv_是一个结构体
struct JNIEnv_ {
const struct JNINativeInterface_ *functions;
#ifdef __cplusplus //省略代码
jstring NewStringUTF(const char *utf) {
return functions->NewStringUTF(this,utf);
}
#endif /* __cplusplus */
};
struct JNINativeInterface_ {
jstring (JNICALL *NewStringUTF)
(JNIEnv *env, const char *utf);
}
那么:
JNIEXPORT jstring JNICALL Java_com_golf_getStringFromC(JNIEnv *env, jclass jcls)
/*
在C中,env中一个指向JNIEnv的一级指针,而JNIEnv又是一个JNINativeInterface_的指针,
即:env是一个指向JNINativeInterface_的二级指针
例当我们调用JNIEnv_结构体里的方法NewStringUTF()时,
实际上也是调用JNINativeInterface_里的方法。
所以,我们对(*env)取值得到JNINativeInterface_的一级指针,
就可以调用NewStringUTF(JNIEnv *env, const char *utf)方法了。
注意:参数需要JNIEnv一级指针
*/
/*
在C++中,env中一个指向JNIEnv的一级指针,而JNIEnv,这时就是JNIEnv_,
所以env可以直接调用NewStringUTF(const char *utf)方法,
可以看到,里面也是调用JNINativeInterface_的NewStringUTF(JNIEnv *env, const char *utf),
而参数里面的JNIEnv,可以直接通过this拿到。
*/
总结:
JNIEnv代表着Java运行环境,可以调用Java中的代码,而为了兼容C,C++混编的情况,JNIEnv会有不同的定义,但都是调用了JNINativeInterface_()结构体里面的方法,为了兼容C++,JNIEnv定义成一个JNIEnv_结构体,里面同样是对JNINativeInterface_方法的调用。由于C++中可以使用this关键字。可以直接拿到JNIEnv指针。