文件位置:libnativehelper/include_jni/jni.h

https://developer.aliyun.com/article/1063454
https://blog.csdn.net/qq_32583189/article/details/53172316
https://blog.csdn.net/ItJavawfc/article/details/81209048
https://blog.csdn.net/shizhonghuo19870328/article/details/52402526

JavaVM与JNIEnv的层级关系

JavaVM是虚拟机在JNI层的代表,每一个虚拟机进程只有一个javaVM。也就是说, 对于我们的JNI 来说, JavaVM 是一个全局变量。
JNIEnv是与线程有关的量,不同线程的JNIEnv彼此独立。

一、JNIEnv

 139 #if defined(__cplusplus)
 140 typedef _JNIEnv JNIEnv;
 141 typedef _JavaVM JavaVM;
 142 #else
 143 typedef const struct JNINativeInterface* JNIEnv;
 144 typedef const struct JNIInvokeInterface* JavaVM;
 145 #endif

对于c++编程语言,JNIEnv的真身是_JNIEnv结构体;对于c语言,可知JNIEnv的真身是JNINativeInterface指针。
所以应用层在调用jni函数时,会有区别:http://xinyiworld.top/wordpress_it/?p=193

所以,JavaVM 和JNIEnv 的使用方法如下:

  1. 对于C
(*env)->方法名(env,参数列表)

(*vm)->方法名(vm,参数列表)
  1. 对于C++
env->方法名(参数列表)

vm->方法名(参数列表)

C++中定义了cplusplus,C语言中没有该定义。即:用cplusplus来识别是C代码还是C++代码。

_JNIEnv

struct _JNIEnv {
    /* do not rename this; it does not seem to be entirely opaque */
    const struct JNINativeInterface* functions;

#if defined(__cplusplus)

#endif /*__cplusplus*/
};

!!_JNIEnv其实是对JNINativeInterface作了一层封装而已!!

JNINativeInterface

  • 模拟JNIEnv的实现

https://www.jianshu.com/p/30cdd4486396

#include<stdio.h>
#include<stdlib.h>

typedef const struct JNINativeInterface_* JNIEnv;
typedef char* jstring;//模拟定义jstring

struct JNINativeInterface_
{
    char* (* NewStringUTF)
        (JNIEnv* env, const char* utf);
};

char* NewStringUTF(JNIEnv* env, const char* utf) {
    return utf;
}

//模拟Java的Native方法
jstring Java_JniDemo_getString(JNIEnv* env) {
    return (*env)->NewStringUTF(env,"模拟JNIEnv");
}

void main() {
    struct JNINativeInterface_ jni_interface;
    jni_interface.NewStringUTF = NewStringUTF;

    JNIEnv jni_env = &jni_interface;

    JNIEnv* env = &jni_env;

    jstring j_string = Java_JniDemo_getString(env);

    printf("%s\n",j_string);

    system("pause");
}

二、JavaVM

同JNIEnv,JavaVM为_JavaVM或JNIInvokeInterface*,_JavaVM是对JNIInvokeInterface的封装。

JNIInvokeInterface

1034 /*
1035  * JNI invocation interface.
1036  */
1037 struct JNIInvokeInterface {
1038     void*       reserved0;
1039     void*       reserved1;
1040     void*       reserved2;
1041 
1042     jint        (*DestroyJavaVM)(JavaVM*);
1043     jint        (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*);
1044     jint        (*DetachCurrentThread)(JavaVM*);
1045     jint        (*GetEnv)(JavaVM*, void**, jint);
1046     jint        (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*);
1047 };

0 条评论

发表回复

您的电子邮箱地址不会被公开。