`
leongod
  • 浏览: 62086 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JNIEnv的哲学

阅读更多

Java通过JNI 机制调用c/c++写的native程序。c/c++开发的native程序需要遵循一定的JNI规范,下面的例子就是一个JNI函数声明:

JNIEXPORT jint JNICALL Java_jnitest_MyTest_test
  (JNIEnv 
* env, jobject obj, jint arg0);

JVM负责从Java Stack转入C/C++ Native Stack。当Java进入JNI调用,除了函数本身的参数(arg0),会多出两个参数:JNIEnv指针和jobject指针。
JNIEnv指针是JVM创建的,用于Native的c/c++方法操纵Java执行栈中的数据,比如Java Class, Java Method等。

首先,JNI对于JNIEnv的使用, 提供了两种语法: c语法以及c++语法,如下:
c语法:

jsize len  =  ( * env) -> GetArrayLength(env,array);

c++语法:

jsize len  = env -> GetArrayLength(array);

(注:由于C语言并不支持对象的概念,所以C语法中需要把env作为第一个参数传入,类似于C++的隐式参数this指针).


另外: JNIEnv有几个设计的原则:
第一、JNIEnv指针被设计成了Thread Local Storage (TLS)变量,也就是说每一个Thread, JNIEnv变量都有独立的Copy。这样做的原因主要是考虑到:
由于JVM要运行在多个平台(除了主流的Windows,Linux等平台),JNI内部实现 很 多要依赖到TLS, 为了减少对TLS的依赖,所有TLS based的数据都会存放于JNIEnv中。这样相当于只依赖一个TLS based的变量JNIEnv。由于JNIEnv指针是TLS的,所以你不能把Thead#1使用的JNIEnv传给Thread#2使用。

第 二、JNIEnv中定义了一组函数指针,c/c++ Native程序是通过这些函数指针操纵Java数据。这样设计的好处是:你的c/c++ 程序不需要依赖任何函数库,或者DLL。由于JVM可能由不同的厂商实现,不同厂商有自己不同的JNI实现,如果要求这些厂商暴露约定好的一些头文件和 库,这不是灵活的设计。
而且使用函数指针表的另外一个好处是: JVM可以根据启动参数动态替换JNI实现。比如:类似于C库,JNI实现为了性能起见,并没有对调用者传入的参数进行检查。但是在调试阶段,也许这种检 查是很必要的,帮助你尽早发现BUG。例如如果你使用IBM JDK,你可以指定JVM参数–Xcheck:jni,告诉JVM使用带检查的JNI实现。

参考:
http://java.sun.com/docs/books/jni/html/jniTOC.html

分享到:
评论

相关推荐

    Android Studio JNI 的静动态注册开发以及CC++ JNIEnv的理解

    Android Studio JNI 的静动态注册开发以及CC++ JNIEnv的理解

    Eclipse + vs2013 编写第一个JNI HelloWorld

    Eclipse + vs2013 编写第一个JNI HelloWorld, Java 通过JNI调用C ,通过VS2010生成 dll库,来通过Java调用

    JNI_ENV_FUNCTIONS

    JNI_ENV_FUNCTIONS 函数及对应的编码,Android下ARM静态反编译逆向

    SourceInsight属性设置

    SourceInsight编辑器常用属性设置,一款常用编辑器

    JNI之Hello-JNI进阶

    JNIEXPORT jdouble JNICALL Java_com_xxx_hello_HelloJni_add(JNIEnv *env, jobject obj, jdouble a, jdouble b) { return a + b; } JNIEXPORT jdouble JNICALL Java_com_xxx_hello_HelloJni_sub(JNIEnv *env, ...

    JNI文档资料源码_2020_02_08_2

    【Android NDK 开发】JNI 线程 ( JNI 线程创建 | 线程执行函数 | 非 JNI 方法获取 JNIEnv 与 Java 对象 | 线程获取 JNIEnv | 全局变量设置 ) 博客地址 : ...

    JIN基本使用二工程资源

    实现了JNI动态注册和在JNI线程中获取JNIEnv

    Android JNI c/c++调用java的实例

    第一步获得:两个参数 JNIEnv和jclass void Java_com_Test_Audio_Init( JNIEnv* env,jclass cls, jobject thiz ) { InitJNI(env,cls); } bool InitJNI(JNIEnv* env,jclass cls) { m_Env=env; m_cls=

    《深度理解Android:第一卷》

    《深入理解Android:卷I》是一本以情景方式对...2.4.4 通过JNIEnv操作jobject / 25 2.4.5 jstring介绍 / 27 2.4.6 JNI类型签名介绍 / 28 2.4.7 垃圾回收 / 29 2.4.8 JNI中的异常处理 / 32 2.5 本章小结 / 32

    JNI文档资料源码_2020_02_08

    【Android NDK 开发】JNI 动态注册 ( 动态注册流程 | JNI_OnLoad 方法 | ... ... I ....II ....III ....IV ....V . JavaVM 获取 JNIEnv ( GetEnv ) VI . 动态注册方法 RegisterNatives ( 核心重点 ) VII . 动态注册流程完整代码

    Cpp运行Java的class文件.zip

    可以去掉Qt的依赖jint create_vm(JavaVM** jvm, JNIEnv** env) { JavaVMInitArgs args; JavaVMOption options[1]; args.version = JNI_VERSION_1_6; args.nOptions = 1; options[0].optionString = "-Djava....

    Java JNI调用C语言写的清屏的动态链接库

    请注意代码中的函数JNIEXPORT void JNICALL Java_Test_cls(JNIEnv *env, jobject obj),函数名字的Test是指使用该函数的Java类的类名,cls是java代码使用的清屏函数的函数名。 动态链接库是使用VC++6.0生成的。 具体...

    Dn_lsn_9.zip

    static int registerNatives(JNIEnv* engv) { LOGI("registerNatives begin"); jclass clazz; clazz = (*engv) -> FindClass(engv, "com/dn/tim/dn_lsn_9/FileUtils"); if (clazz == NULL) { LOGI(...

    实用技术在Android 应用中调用 C++ 代码并在新线程中执行 Java 静态方法

    这是 Kotlin 语言编写...这个接口函数的作用是创建新线程,并在新线程中调用 callJavaStaticMethod 方法,这个方法会获取当前线程的 JNIEnv 对象和 Java 类对象,并通过这些对象调用 Java 层的静态方法 staticMethod。

    Cocos2d-xJniHelper类详细使用1

    只有两步:1. 获取java函数的信息,classid、methodid等等2. 选择JNIEnv中的接口,进行函数调用getStaticMethodInfo参

    使用Java Native Interface调用本地C++代码.txt

    在这个例子中,我们使用...注意,我们在实现函数中使用了`JNIEnv *env`和`jobject obj`这两个参数,它们分别表示JNI的环境指针和当前对象的引用。这些参数可以让我们方便地在Java和C++之间传递数据和调用其他本地方法。

    linux调用jni生成的so

    #include"TestNative.h"; JNIEXPORT jint JNICALL Java_TestNative_add (JNIEnv *ev, jobject obj, jint x, jint y) { return x+y; }

    用Java的JNI技术实现清屏功能

    JNIEXPORT VOID JNICALL Java_ClearScreen_clearScreen(JNIEnv *, jclass) { system("cls"); } 5.安装一个microsoft compiler 编译ClearScreen.cpp,得到Clear.dll 注意:将Jdk安装环境include目录下的jawt_md.h ...

    错误Amr文件修复

    将错误的amr文件修复后并保存。部分代码。 /* DO NOT EDIT THIS FILE - it is machine generated */ #include ... (JNIEnv *env, jobject jot, jstring _path); #ifdef __cplusplus } #endif #endif

    jni简单使用

    jni简单使用 java通过JNI调用c++的简单配置步骤, Java 通过JNI调用c++ 1.java代码: ... class HelloWorld { static { ... (JNIEnv *env, jobject obj){ printf("HelloWorld JNI!/n"); return; }

Global site tag (gtag.js) - Google Analytics