返回介绍

2.3 JNIEnv 类型和 jobject 类型

发布于 2024-10-10 22:32:14 字数 3468 浏览 0 评论 0 收藏 0

上一节介绍的是一个简单的应用,说明 JNI 是怎么工作的,这一节介绍本地方法 sayHello 的参数及其使用。

首先来看一下 C++中的 sayHello 方法的实现:

2.3.1 JNIEnv 类型

JNIEnv 类型实际上代表了 Java 环境,通过 JNIEnv*指针就可以对 Java 端的代码进行操作。例如,创建 Java 类中的对象,调用 Java 对象的方法,获取 Java 对象中的属性等。

JNIEnv 类中有很多函数可以用,如下所示:

·NewObject:创建 Java 类中的对象。

·NewString:创建 Java 类中的 String 对象。

·New<Type>Array:创建类型为 Type 的数组对象。

·Get<Type>Field:获取类型为 Type 的字段。

·Set<Type>Field:设置类型为 Type 的字段的值。

·GetStatic<Type>Field:获取类型为 Type 的 static 的字段。

·SetStatic<Type>Field:设置类型为 Type 的 static 的字段的值。

·Call<Type>Method:调用返回类型为 Type 的方法。

·CallStatic<Type>Method:调用返回值类型为 Type 的 static 方法。

更多的函数使用可以查看 jni.h 文件中的函数名称。

2.3.2 jobject 参数 obj

如果 native 方法不是 static,obj 就代表 native 方法的类实例。

如果 native 方法是 static,obj 就代表 native 方法的类的 class 对象实例(static 方法不需要类实例的,所以就代表这个类的 class 对象)。

2.3.3 Java 类型和 native 中的类型映射关系

Java 和 C++中的基本类型的映射关系参见表 2-1。

表 2-1 Java 和 C++中的基本类型的映射关系

具体的说明可以查看 jni.h 文件。

2.3.4 jclass 类型

为了能够在 C/C++中使用 Java 类,jni.h 头文件中专门定义了 jclass 类型来表示 Java 中的 Class 类。

JNIEnv 类中有如下几个简单的函数可以取得 jclass:

·jclass FindClass(const char*clsName):通过类的名称(类的全名,这时候包名不是用点号而是用/来区分的)来获取 jclass。如:jclass str=env->FindClass("java/lang/String");获取 Java 中的 String 对象的 class 对象。

·jclass GetObjectClass(jobject obj):通过对象实例来获取 jclass,相当于 Java 中的 getClass 方法。

·jclass GetSuperClass(jclass obj):通过 jclass 可以获取其父类的 jclass 对象。

2.3.5 native 中访问 Java 层代码

在 C/C++本地代码中访问 Java 端的代码,一个常见的应用就是获取类的属性和调用类的方法,为了在 C/C++中表示属性和方法,JNI 在 jni.h 头文件中定义了 jfieldId、jmethodID 类型来分别代表 Java 端的属性和方法。在访问或者设置 Java 属性的时候,首先就要先在本地代码取得代表该 Java 属性的 jfieldID,然后才能在本地代码中进行 Java 属性操作,同样,需要调用 Java 端的方法时,也是需要取得代表该方法的 jmethodID 才能进行 Java 方法调用。

使用 JNIEnv 的如下方法:

·GetFieldID/GetMethodID

·GetStaticFieldID/GetStaticMethodID

来取得相应的 jfieldID 和 jmethodID。

下面来具体看一下这几个方法。

GetFieldID 方法如下:

方法的参数说明:

·clazz:这个方法依赖的类对象的 class 对象。

·name:这个字段的名称。

·sign:这个字段的签名(每个变量,每个方法都是有签名的)。

怎么查看类中的字段和方法的签名呢?使用 javap 命令,如下所示。

GetMethodID 也能够取得构造函数的 jmethodID,创建一个 Java 对象时可以调用指定的构造方法,后续将向大家介绍,如:

签名的格式见表 2-2。

表 2-2 签名的格式

下面来看一例子:

上面的 native 代码中,首先取得 property 字段,因为 property 字段是 int 类型的,所以在签名中传入“I”,取得方法 function 的 ID 时:

签名为(Iljava/util/Date;[I)I。

关于 GetStaticFieldID/GetStaticMethodID 这两个方法的用法大同小异,区别在于这两个方法是获取静态字段和方法的 ID。

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

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

发布评论

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