第二天
c中获取java的属性,并修改属性;c调用java中的方法
一、公共成员属性
1、首先java层定义native方法 以及调用方法
package com.sohubill.ndkstudy;
public class Study1 {
static {
System.load("G:\\NDKProjcet\\NdkJni\\x64\\Debug\\NdkJni.dll");
}
public String mName = "bill";
public native void changeName();
public static void main(String[] args) {
Study1 study = new Study1();
System.out.println("java中原来的name = "+study.mName);
study.changeName();
System.out.println("经过navtice改变后的名字"+study.mName);
}
}
2、头文件添加方法
#include "jni.h"
#ifndef _Included_com_sohubill_ndkstudy_Study1
#define _Included_com_sohubill_ndkstudy_Study1
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_com_sohubill_ndkstudy_Study1_changeName
(JNIEnv*, jobject);
#ifdef __cplusplus
}
#endif
#endif
3、c文件实现方法
#include "com_sohubill_ndkstudy_Study1.h"
JNIEXPORT void JNICALL Java_com_sohubill_ndkstudy_Study1_changeName
(JNIEnv* env, jobject jobj) {
//3、需要得到jclass需要用到GetObjectClass方法,参数是(JNIEnv *env, jclass jobj);
jclass j_class = (*env)->GetObjectClass(env, jobj);
//2、需要得到jfieldID需要用到GetFieldID方法,参数是(JNIEnv *env, jclass clazz, const char *name, const char *sig);
// 由此可知需要获取jclass *sig是方法签名,Java中类签名规则是L+类全名(.改成/)+; int 是I,float是F等
jfieldID j_fieldID = (*env)->GetFieldID(env, j_class, "mName", "Ljava/lang/String;");
//1、需要得到java中的String元素需要用到*env中 GetObjectField方法,参数是 (JNIEnv *env, jobject obj, jfieldID fieldID);
// 由此可知需要获得jfieldID;
jstring j_str = (*env)->GetObjectField(env, jobj, j_fieldID);
char* c_str = (*env)->GetStringUTFChars(env, j_str, NULL);
printf("c中得到的java字符串是:%s", c_str);
//4、修改java中的属性
jstring j_newStr = (*env)->NewStringUTF(env, "jack");
(*env)->SetObjectField(env, jobj, j_fieldID, j_newStr);
//5、j_str没有使用了,需要释放资源。j_newStr会返回给java层,还在使用不能释放内存.
(*env)->ReleaseStringUTFChars(env, j_str, c_str);
}
运行结果是:
java中原来的name = bill
经过navtice改变后的名字jack
c中得到的java字符串是:bill
二、公共静态属性
1、java 定义静态变量和native静态方法,并调用方法
package com.sohubill.ndkstudy;
public class Study1 {
static {
System.load("G:\\NDKProjcet\\NdkJni\\x64\\Debug\\NdkJni.dll");
}
public static int age = 30;
public static native void changeAge();
public static void main(String[] args) {
System.out.println("java中原来的name = "+age);
changeAge();
System.out.println("经过navtice改变后的名字"+age);
}
}
2、头文件添加对应的方法。这里是静态方法参数不是jboject 是jclass
#include "jni.h"
#ifndef _Included_com_sohubill_ndkstudy_Study1
#define _Included_com_sohubill_ndkstudy_Study1
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_com_sohubill_ndkstudy_Study1_changeAge
(JNIEnv*, jclass);
#ifdef __cplusplus
}
#endif
#endif
3、c文件实现方法
#include "com_sohubill_ndkstudy_Study1.h"
JNIEXPORT void JNICALL Java_com_sohubill_ndkstudy_Study1_changeAge
(JNIEnv* env, jclass jclass) {
//2、需要得到jfieldID需要用到GetFieldID方法,参数是(JNIEnv *env, jclass clazz, const char *name, const char *sig);
// 由此可知需要获取jclass *sig是方法签名,Java中类签名规则是L+类全名(.改成/)+; int 是I,float是F等
jfieldID j_fieldID = (*env)->GetStaticFieldID(env, jclass, "age", "I");
//1、需要得到java中的静态int元素需要用到*env中 GetStaticIntField方法,参数是 (JNIEnv *env, jclass clazz, jfieldID fieldID);
// 由此可知需要获得jfieldID;
jint j_age = (*env)->GetStaticIntField(env, jclass, j_fieldID);
printf("c中得到的java整数是:%d", j_age);
j_age = j_age + 15;
//3、修改java中的属性
(*env)->SetStaticIntField(env,jclass , j_fieldID, j_age);
}
三、c中调用java中的静态方法
1、java 定义一个方法以及实现,定义一个native方法,在c中实现这个navive访问java中的方法
package com.sohubill.ndkstudy;
public class Study1 {
static {
System.load("G:\\NDKProjcet\\NdkJni\\x64\\Debug\\NdkJni.dll");
}
public static int add(int x,int y) {
return x+y;
}
public static native int useJavaMethod();
public static void main(String[] args) {
int res = useJavaMethod();
System.out.println("c中调用java的add方法并传入参数12,13,运行结果是:"+res);
}
}
2、头文件添加对应的方法。这里是静态方法参数不是jboject 是jclass
#include "jni.h"
#ifndef _Included_com_sohubill_ndkstudy_Study1
#define _Included_com_sohubill_ndkstudy_Study1
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_com_sohubill_ndkstudy_Study1_useJavaMethod
(JNIEnv*, jclass);
#ifdef __cplusplus
}
#endif
#endif
3、c文件实现方法
#include "com_sohubill_ndkstudy_Study1.h"
JNIEXPORT jint JNICALL Java_com_sohubill_ndkstudy_Study1_useJavaMethod
(JNIEnv* env, jclass jclass) {
//2、利用 GetStaticMethodID获取jmethodID 参数时(JNIEnv *env, jclass clazz, const char *name, const char *sig);
// *sig是方法签名 规则是【(参数...)返回值类型】比如 int XXX(int,int)则是(II)I void XXX(double,int)则是(DI)V
jmethodID j_methodID =(*env)->GetStaticMethodID(env,jclass,"add","(II)I");
//1、利用 CallStaticIntMethod 调用java中的静态方法, 参数(JNIEnv *env, jclass clazz, jmethodID methodID, ...);
// 需要获取jmethodID
jint j_res = (*env)->CallStaticIntMethod(env, jclass, j_methodID, 12, 13);
return j_res;
}
四、c中调用java的成员方法与静态方法类似。只是jclass换成jobject