`

访问JNI函数:JNIEnv自变量

 
阅读更多

利用JNI函数,程序员可从一个固有方法的内部与JVM打交道。正如大家在前面的例子中看到的那样,每个JNI固有方法都会接收一个特殊的自变量作为自己 的第一个参数:JNIEnv自变量——它是指向类型为JNIEnv_的一个特殊JNI数据结构的指针。JNI数据结构的一个元素是指向由JVM生成的一个 数组的指针;该数组的每个元素都是指向一个JNI函数的指针。可从固有方法的内部发出对JNI函数的调用,做法是撤消对这些指针的引用(具体的操作实际很 简单)。每种JVM都以自己的方式实现了JNI函数,但它们的地址肯定位于预先定义好的偏移处。
利用JNIEnv自变量,程序员可访问一系列函数。这些函数可划分为下述类别:
■获取版本信息
■进行类和对象操作
■控制对Java对象的全局和局部引用
■访问实例字段和静态字段
■调用实例方法和静态方法
■执行字串和数组操作
■产生和控制Java异常
JNI函数的数量相当多,这里不再详述。相反,我会向大家揭示使用这些函数时背后的一些基本原理。欲了解更详细的情况,请参阅自己所用编译器的JNI文档。
若观察一下jni.h头文件,就会发现在#ifdef _cplusplus预处理器条件的内部,当由C++编译器编译时,JNIEnv_结构被定义成一个类。这个类包含了大量内嵌函数。通过一种简单而且熟悉 的语法,这些函数让我们可以从容访问JNI函数。例如,前例包含了下面这行代码:
(*jEnv)->ReleaseStringUTFChars(jEnv, jMsg,msg);
它在C++里可改写成下面这个样子:
jEnv->ReleaseStringUTFChars(jMsg,msg);
大家可注意到自己不再需要同时撤消对jEnv的两个引用,相同的指针不再作为第一个参数传递给JNI函数调用。在这些例子剩下的地方,我会使用C++风格的代码。

1. 访问Java字串
作为访问JNI函数的一个例子,请思考上述的代码。在这里,我们利用JNIEnv的自变量jEnv来访问一个 Java字串。Java字串采取的是Unicode格式,所以假若收到这样一个字串,并想把它传给一个非Unicode函数(如printf()),首先 必须用JNI函数GetStringUTFChars()将其转换成ASCII字符。该函数能接收一个Java字串,然后把它转换成UTF-8字符(用8 位宽度容纳ASCII值,或用16位宽度容纳Unicode;若原始字串的内容完全由ASCII构成,那么结果字串也是ASCII)。
GetStringUTFChars是JNIEnv间接指向的那个结构里的一个字段,而这个字段又是指向一个函数的指针。为访问JNI函数,我们用传统的C语法来调用一个函数(通过指针)。利用上述形式可实现对所有JNI函数的访问。

分享到:
评论

相关推荐

    Think in Java(中文版)chm格式

    A.1.2 访问JNI函数:JNIEnv自变量 A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32...

    JAVA_Thinking in Java

    A.1.2 访问JNI函数:JNIEnv自变量 A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3...

    Java初学者入门教学

    A.1.2 访问JNI函数:JNIEnv自变量 A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3...

    ThinkInJava

    A.1.2 访问JNI函数:JNIEnv自变量 A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3...

    java 编程入门思考

    A.1.2 访问JNI函数:JNIEnv自变量 A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3...

    thinkinjava

    A.1.2 访问JNI函数:JNIEnv自变量 A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3...

    Thinking in Java 中文第四版+习题答案

    A.1.2 访问JNI函数:JNIEnv自变量 A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 ...

    Thinking in Java简体中文(全)

    A.1.2 访问JNI函数:JNIEnv自变量 A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3...

    java联想(中文)

    A.1.2 访问JNI函数:JNIEnv自变量 A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3...

    Thinking in Java(中文版 由yyc,spirit整理).chm

    A.1.2 访问JNI函数:JNIEnv自变量 A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3...

    JAVA_Thinking in Java(中文版 由yyc,spirit整理).chm

    A.1.2 访问JNI函数:JNIEnv自变量 A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3...

    JNI完全技术手册 带完整书签

    3、实例三、在jni函数中访问java类中的对象实例域... 58 4、实例四:在jni函数中访问类的静态实例域... 60 5、实例五:在jni函数中调用java对象的方法... 60 6、实例六:在jni函数中调用java类的静态方法... 61 ...

    jni.h头文件

    4. **JNI环境变量**:`JNIEnv`结构体中包含了多个函数指针,这些函数指针对应于实际的JNI函数实现。通过这个结构体,本地方法可以访问和操作Java虚拟机(JVM)的各种服务。 5. **异常处理**:JNI提供了处理和抛出...

    android_jni操作指南.zip

    2. 定义JNI函数:遵循JNI函数命名规则,例如`JNIEXPORT void JNICALL Java_MyPackage_MyClass_myMethod(JNIEnv *env, jobject obj)`。 四、本地方法注册 1. `JNI_OnLoad`:在C/C++代码中,需要有一个`JNI_OnLoad`...

    android 使用jni调用c++

    `JNIEnv *env`参数是JNI接口指针,用于访问JNI函数。`jobject`参数是Java对象的引用,通常是你调用JNI函数的Java类实例。 为了从Java层调用这个C++函数,我们需要生成JNI接口。SWIG(Simplified Wrapper and ...

    JNI程序员指南与规范_liono8x_jni指南_

    3. **编写JNI头文件**:使用`javah`工具,根据Java类中的native方法生成对应的C/C++头文件,该头文件包含了JNI函数声明。 4. **实现本地方法**:在C/C++源文件中,根据生成的头文件实现本地方法,这些方法会与Java...

    android jni 调用本地函数 c++ 格式

    JNI函数签名遵循特定的格式,例如`JNIEnv *`参数表示JNI环境,`jobject`表示Java对象实例。`JNIEXPORT`和`JNICALL`是预定义的宏,用于指定导出和调用约定。 7. **调用Java对象和成员** JNI提供了一系列接口来访问...

    android ndk开发步骤和实例

    通过这个实例,你已经掌握了Android NDK开发的基本流程,包括创建工程、编写JNI函数、配置构建脚本以及在Java代码中调用这些函数。随着经验的积累,你可以进一步学习更高级的主题,如多线程、动态链接库、性能优化等...

    android studio JNI demo

    然后,你可以在模拟器或设备上运行应用,测试JNI函数的执行。 7. **调试JNI代码**:Android Studio提供了对JNI代码的调试支持,你可以设置断点,查看变量值,以及进行其他调试操作。 8. **注意事项**:使用JNI时要...

Global site tag (gtag.js) - Google Analytics