您的位置:首页 > 编程语言 > C语言/C++

NDK开发学习笔记—C/C++访问java成员

2016-11-03 00:50 609 查看

获取java的成员签名





C访问java的属性

//java代码
public String key = "world";

public static int count = 10;
//访问属性,返回修改之后的属性内容
public native String accessField();

public native void accessStaticField();

//C代码
//访问属性 修改属性key
JNIEXPORT jstring JNICALL Java_com_dongnaoedu_jni_JniTest_accessField
(JNIEnv *env, jobject jobj){
//jobj是t对象,JniTest.class
jclass cls = (*env)->GetObjectClass(env, jobj);
//jfieldID
//env,jclass,属性名称,属性签名
jfieldID fid = (*env)->GetFieldID(env, cls, "key", "Ljava/lang/String;");

//hello>> hello world
//获取key属性的值
//Get<Type>Field
jstring jstr = (*env)->GetObjectField(env, jobj, fid);

//jstring -> c字符串
//isCopy 是否复制(true代表赋值,false不复制)
char *c_str = (*env)->GetStringUTFChars(env,jstr,JNI_FALSE);
//拼接得到新的字符串
char text[20] = "hello ";
strcat(text,c_str);

//c字符串 ->jstring
jstring new_jstr = (*env)->NewStringUTF(env, text);

//修改key
//Set<Type>Field
(*env)->SetObjectField(env, jobj, fid, new_jstr);

return new_jstr;
}

//访问静态属性
JNIEXPORT void JNICALL Java_com_dongnaoedu_jni_JniTest_accessStaticField
(JNIEnv *env, jobject jobj){
//jclass
jclass cls = (*env)->GetObjectClass(env, jobj);
//jfieldID
jfieldID fid = (*env)->GetStaticFieldID(env, cls, "count", "I");
//GetStatic<Type>Field
jint count = (*env)->GetStaticIntField(env, cls, fid);
count++;
//修改
//SetStatic<Type>Field
(*env)->SetStaticIntField(env,cls,fid,count);
}


C访问java方法

//java代码
public native void accessMethod();

public native void accessStaticMethod();

//产生指定范围的随机数
public int genRandomInt(int max){
System.out.println("genRandomInt 执行了...");
return new Random().nextInt(max);
}

//产生UUID字符串
public static String getUUID(){
return UUID.randomUUID().toString();
}

//C代码
//访问java方法
JNIEXPORT void JNICALL Java_com_dongnaoedu_jni_JniTest_accessMethod
(JNIEnv *env, jobject jobj){
//jclass
jclass cls = (*env)->GetObjectClass(env, jobj);
//jmethodID
jmethodID mid = (*env)->GetMethodID(env, cls, "genRandomInt", "(I)I");
//调用
//Call<Type>Method
jint random = (*env)->CallIntMethod(env, jobj, mid, 200);
printf("random num:%ld",random);

//.....
}

//静态方法
JNIEXPORT void JNICALL Java_com_dongnaoedu_jni_JniTest_accessStaticMethod
(JNIEnv *env, jobject jobj){
//jclass
jclass cls = (*env)->GetObjectClass(env, jobj);
//jmethodID
jmethodID mid = (*env)->GetStaticMethodID(env, cls, "getUUID", "()Ljava/lang/String;");

//调用
//CallStatic<Type>Method
jstring uuid = (*env)->CallStaticObjectMethod(env, cls, mid);

//随机文件名称 uuid.txt
//jstring -> char*
//isCopy JNI_FALSE,代表java和c操作的是同一个字符串
char *uuid_str = (*env)->GetStringUTFChars(env, uuid, JNI_FALSE);
//拼接
char filename[100];
sprintf(filename, "D://%s.txt",uuid_str);
FILE *fp = fopen(filename,"w");
fputs("i love jason", fp);
fclose(fp);
}


C访问java构造函数

//java代码
public native Date accessConstructor();

//C代码
//使用java.util.Date产生一个当前的时间戳
JNIEXPORT jobject JNICALL Java_com_dongnaoedu_jni_JniTest_accessConstructor
(JNIEnv *env, jobject jobj){
jclass cls = (*env)->FindClass(env, "java/util/Date");
//jmethodID
jmethodID constructor_mid = (*env)->GetMethodID(env, cls, "<init>", "()V");
//实例化一个Date对象
jobject date_obj = (*env)->NewObject(env, cls, constructor_mid);
//调用getTime方法
jmethodID mid = (*env)->GetMethodID(env, cls, "getTime", "()J");
jlong time = (*env)->CallLongMethod(env, date_obj, mid);

printf("\ntime:%lld\n",time);

return date_obj;
}


C访问java父类的方法

//java代码
public class Human {
public void sayHi(){
System.out.println(打招呼....);
}
}

//java代码
//public native void accessNonvirtualMethod();

//C代码
//调用父类的方法
JNIEXPORT void JNICALL Java_com_dongnaoedu_jni_JniTest_accessNonvirtualMethod
(JNIEnv *env, jobject jobj){
jclass cls = (*env)->GetObjectClass(env, jobj);
//获取man属性(对象)
jfieldID fid = (*env)->GetFieldID(env, cls, "human", "Lcom/dongnaoedu/jni/Human;");
//获取
jobject human_obj = (*env)->GetObjectField(env, jobj, fid);

//执行sayHi方法
jclass human_cls = (*env)->FindClass(env, "com/dongnaoedu/jni/Human"); //注意:传父类的名称
jmethodID mid = (*env)->GetMethodID(env, human_cls, "sayHi", "()V");

//执行
//(*env)->CallObjectMethod(env, human_obj, mid);
//调用的父类的方法
(*env)->CallNonvirtualObjectMethod(env, human_obj, human_cls, mid);
}


C访问java数组

//java代码
public native void giveArray(int[] array);

public native int[] getArray(int len);

int[] array = {9,100,10,37,5,10};
//排序
t.giveArray(array);
for (int i : array) {
System.out.println(i);
}

int[] array2 = t.getArray(10);
System.out.println("------------");
for (int i : array2) {
System.out.println(i);
}

//C代码
int compare(int *a,int *b){
return (*a) - (*b);
}

//传入
JNIEXPORT void JNICALL Java_com_dongnaoedu_jni_JniTest_giveArray
(JNIEnv *env, jobject jobj, jintArray arr){
//jintArray -> jint指针 -> c int 数组
jint *elems = (*env)->GetIntArrayElements(env, arr, NULL);
//printf("%#x,%#x\n", &elems, &arr);

//数组的长度
int len = (*env)->GetArrayLength(env, arr);
//排序
qsort(elems, len, sizeof(jint), compare);

//同步
//mode
//0, Java数组进行更新,并且释放C/C++数组
//JNI_ABORT, Java数组不进行更新,但是释放C/C++数组
//JNI_COMMIT,Java数组进行更新,不释放C/C++数组(函数执行完,数组还是会释放)
(*env)->ReleaseIntArrayElements(env, arr, elems, JNI_COMMIT);
}

//返回数组
JNIEXPORT jintArray JNICALL Java_com_dongnaoedu_jni_JniTest_getArray(JNIEnv *env, jobject jobj, jint len){
//创建一个指定大小的数组
jintArray jint_arr = (*env)->NewIntArray(env, len);
jint *elems = (*env)->GetIntArrayElements(env, jint_arr, NULL);
int i = 0;
for (; i < len; i++){
elems[i] = i;
}

//同步
(*env)->ReleaseIntArrayElements(env, jint_arr, elems, 0);

return jint_arr;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: