04 jni调用java方法

JNI本地方法访问Java属性和方法

在JNI调用中,不仅仅Java可以调用本地方法,本地代码也可以调用Java中的方法和成员变量。在Java1.0中“原始的”Java到C的绑定中,程序员可以直接访问对象数据域。然而,直接方法要求虚拟机暴露他们的内部数据布局,基于这个原因,JNI要求程序员通过特殊的JNI函数来获取和设置数据以及调用java方法。

 

 

  • 取得代表属性和方法的jfieldID和jmethodID

 

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

 

使用JNIEnv提供的JNI方法,我们就可以获得属性和方法相对应的jfieldID和jmethodID:

 

l GetFieldID :取得成员变量的id

l GetStaticFieldID :取得静态成员变量的id

l GetMethodID :取得方法的id

l GetStaticMethodID :取得静态方法的id

 

jfieldID GetFieldID(jclass clazz, const char *name,const char *sig)

jfieldID GetStaticFieldID(jclass clazz, const char*name, const char *sig)

jmethodID GetStaticMethodID(jclass clazz, const char*name, const char *sig)

jmethodID GetMethodID(jclass clazz, const char *name,constchar *sig)

 

第一个参数jclassclazz :

上一节讲到的jclass类型,相当于Java中的Class类,代表一个Java类,而这里面的代表的就是我们操作的Class类,我们要从这个类里面取的属性和方法的ID。

 

第二个参数constchar *name:

这是一个常量字符数组,代表我们要取得的方法名或者变量名。

 

第三个参数constchar *sig:

这也是一个常量字符数组,代表我们要取得的方法或变量的签名。(变量类型)

 

类型签名Java 类型类型签名Java 类型
ZbooleanVvoid
BbyteLjava/lang/StringString
CcharLjava/lang/ObjectObject
SshortFfloat
IintDdouble
JlongLJava对象以L开头,然后以“/”分隔包的完整类型,

 

示例:String substr(String str, int idx, int count);

对应的类型签名(Ljava/lang/String;II)Ljava/lang/String

 

  • 获取/设置 属性/静态属性

获取属性/静态属性的形式:

Get<Type>Field GetStatic<Type>Field。

设置属性/静态属性的形式:

Set<Type>Field SetStatic<Type>Field。

 

取得成员属性:

jobject GetObjectField(jobjectobj, jfieldID fieldID);

jboolean GetBooleanField(jobjectobj, jfieldID fieldID);

jbyte GetByteField(jobjectobj, jfieldID fieldID);

 

取得静态属性:

jobject GetStaticObjectField(jclassclazz, jfieldID fieldID);

jboolean GetStaticBooleanField(jclassclazz, jfieldID fieldID);

jbyte GetStaticByteField(jclassclazz, jfieldID fieldID);

Get方法的第一个参数代表要获取的属性所属对象或jclass对象,第二个参数即属性ID。

 

设置成员属性:

void SetObjectField(jobjectobj, jfieldID fieldID, jobject val);

void SetBooleanField(jobjectobj, jfieldID fieldID,jboolean val);

void SetByteField(jobjectobj, jfieldID fieldID, jbyte val);

 

设置静态属性:

void SetStaticObjectField(jobjectobj, jfieldID fieldID, jobject val);

void SetStaticBooleanField(jobjectobj, jfieldID fieldID,jboolean val);

void SetStaticByteField(jobjectobj, jfieldID fieldID, jbyte val);

Set方法的第一个参数代表要设置的属性所属的对象或jclass对象,第二个参数即属性ID,第三个参数代表要设置的值。

 

 

  • 调用方法

 

取得了代表方法和静态方法的jmethodID,就可以用在JNIEnv中提供的方法来调用方法和静态方法。

 

调用普通方法:

Call<Type>Method(jobject obj, jmethodID methodID,...);

Call<Type>MethodV(jobject obj, jmethodID methodID,va_listargs);

Call<Type>tMethodA(jobject obj, jmethodID methodID,constjvalue *args);

 

调用静态方法:

CallStatic<Type>Method(jclass clazz, jmethodID methodID,...);

CallStatic<Type>MethodV(jclass clazz, jmethodID methodID,va_listargs);

CallStatic<Type>tMethodA(jclass clazz, jmethodID methodID,constjvalue *args);

 

上面的Type这个方法的返回值类型,如Int,Char,Byte等等。

第一个参数代表调用的这个方法所属于的对象,或者这个静态方法所属的类。

第二个参数代表jmethodID。

后面的参数,就代表这个方法的参数列表了。

 

 

本地代码部分:

//首先取得要调用的方法所在的类的Class对象,在C/C++中即jclass对象

jclass clazz_NativeTest=env->FindClass("cn/itcast/NativeTest");

//取得jmethodID

jmethodID id_show=env->GetMethodID(clazz_NativeTest,“show”,"(I)V");

//调用java函数

env->CallIntMethod(obj, id_show, i); //i类型为 jint

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值