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

时间: 2024-09-22 00:20:44

访问JNI函数:JNIEnv自变量的相关文章

《Java 本地接口规范》- JNI 函数(二)

对象操作   AllocObject jobjectAllocObject(JNIEnv *env, jclass clazz); 分配新 Java 对象而不调用该对象的任何构造函数.返回该对象的引用. clazz 参数务必不要引用数组类. 参数: env:JNI 接口指针. clazz:Java 类对象. 返回值: 返回 Java 对象.如果无法构造该对象,则返回NULL. 抛出: InstantiationException:如果该类为一个接口或抽象类. OutOfMemoryError:如

《Java 本地接口规范》- JNI 函数(一)

JNI 函数 本章为 JNI 函数提供参考信息.其中列出了全部 JNI 函数,同时也给出了 JNI 函数表的准确布局. 注意:"必须"一词用于约束 JNI 编程人员.例如,当说明某个 JNI 函数必须接收非空对象时,就应确保不要向该 JNI 函数传递 NULL.这时,JNI 实现将无需在该 JNI 函数中执行 NULL 指针检查. 本章的部分资料改编自 Netscape 的 JRI 文档. 该参考资料按用法对函数进行组织.参考部分按下列函数区域进行组织: 版本信息 类操作 异常 全局及

“无法访问G: 函数不正确”的解决方法

符时总提示:无法访问G: 函数不正确.(如下图) 原来刻录机硬件是没有故障,而是系统的一些设置出了点问题.解决方法如下: 打开"运行"对话框,输入:services.msc,点击确定后打开"服务" 对话框,在"服务(本地)"列表中找到 "IMAPI CD-Burning COM Service"(如下图). 让我们先来看看此服务的描述:"用Image Mastering Applications Programmin

电脑提示“无法访问G:\函数不正确”怎么办

  用光驱将光盘上的内容复制到电脑中的时候,突然提示数据错误而无法复制,之后,光驱就再也打不开了,双击光驱盘符时总提示:无法访问G: 函数不正确.(如下图)   我用的是SONY的CD刻录机,老机子了,工作一直是任劳任怨.鞠躬尽瘁.突然发生这种情况心里不禁也纳闷:难道机子真老了,想退休了? 立刻到网上百度了一下,很快就找到了问题缘由所在.原来刻录机硬件是没有故障,而是系统的一些设置出了点问题.解决方法如下: 打开"运行"对话框,输入:services.msc,点击确定后打开"

link中是否能定义友元函数?友元函数是不是可以访问成员函数?

问题描述 link中是否能定义友元函数?友元函数是不是可以访问成员函数? link中是否能定义友元函数?友元函数是不是可以访问成员函数? 解决方案 C#不支持友元.VB倒是支持,不过和C++的友元不是一回事.VB的友元相当于C#的internal如果你想让一个类操作另一个类的私有成员,可以定义为嵌套类 解决方案二: 可以.友元.(公共)成员.私有函数只是可见性不同,没有本质的不同.除非是静态函数,不能调用非静态函数.

android-在Activity中如何访问fragment函数

问题描述 在Activity中如何访问fragment函数 我的Activity中有几个fragment.我想要在这个Activity中访问在其中一个fragment创建的函数 Fragment: public class RandomFragment extends Fragment { public void randomfuntion (){ } } Activity: public class Main extends FragmentActivity{ Fragment randomn

JAVA JNI函数的注册过程详细介绍_java

JAVA JNI函数的注册过程详细介绍 我们在java中调用Native code的时候,一般是通过JNI来实现的,我们只需要在java类中加载本地.so库文件,并声明native方法,然后在需要调用的地方调用即可,至于java中native方法的具体实现,全部交给了Native层.我们要在java中正确地调用到本地代码中对应函数的前提是什么呢?答案就是通过一定的机制建立java中native方法和本地代码中函数的一一对应关系,那么这种机制是什么呢?就是JNI函数的注册机制. JNI函数的注册有

《Java 本地接口规范》- JNI 函数(三)

字符串操作   NewString jstringNewString(JNIEnv *env, const jchar *unicodeChars, jsize len); 利用 Unicode 字符数组构造新的 java.lang.String 对象. 参数: env:JNI 接口指针. unicodeChars:指向 Unicode 字符串的指针. len:Unicode 字符串的长度. 返回值: Java 字符串对象.如果无法构造该字符串,则为 NULL. 抛出: OutOfMemoryE

常用的一些用于创建和初始化JVM的JNI函数

随着计算机技术的不断发展,多种编程语言之间的相互调用变得越来越常见,如 C++/C++.RPG.COBOL, 以及 Java 语言之间的相互调用.JNI(Java http://www.aliyun.com/zixun/aggregation/16820.html">Native Interface,也称 java 本机接口)是一系列标准的 Java API.它支持 Java 语言和其它编程语言之间的相互调用.但是,JNI 是一把双刃剑,为开发人员带来极大的便利的同时也引入了潜在的威胁.如