返回介绍

A.1.2 访问 JNI 函数:JNIEnv 自变量

发布于 2024-10-15 23:56:37 字数 1422 浏览 0 评论 0 收藏 0

利用 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 函数的访问。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文