安卓Java

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指针。

上一篇下一篇

猜你喜欢

热点阅读