JNI笔记 C访问java属性方法

1 C访问Java非静态成员变量
c代码

JNIEXPORT jstring JNICALL Java_com_yeliang_JniTest_accessField(JNIEnv *env, jobject jobj){
    //在java中新建JniTest对象 JniTest jniTest = new JniTest();
    //1 根据jobject获得jclass对象   jobj是jniTest对象 
    jclass cls = (*env)->GetObjectClass(env, jobj);

    //2 获得成员变量 jfieldID  
    jfieldID field = (*env)->GetFieldID(env, cls, "field", "Ljava/lang/String;");

    //yeliang -->Mr yeliang  修改变量名字
    //3 获取field属性的值  Get<Type>Field
    jstring jstr = (*env)->GetObjectField(env, jobj, field);
    //printf("jstr:%#x\n", &jstr);

    //jstring->c字符串
    //4 根据field的值重新定义一个char对象   isCopy 是否赋值 (true代表复制 false代表不复制)
    char *c_str = (*env)->GetStringUTFChars(env, jstr, JNI_FALSE);

    //5 拼接得到的新字符串
    char text[20] = "super ";
    strcat(text, c_str);

    //6 根据字符数组重新生成字符串  c字符串 -> jstring
    jstring new_jstr = (*env)->NewStringUTF(env,text);

    //7 修改java中的field
    (*env)->SetObjectField(env,jobj,field,new_jstr);

    //printf("new_jstr:%#x\n",&new_jstr);
    return new_jstr;
};

java代码

public native String accessField();

public String field = "yeliang";

public static void main(String[] args) {        
        JniTest jniTest = new JniTest();
        System.out.println("jni修改前属性值为field="+jniTest.field);
        jniTest.accessField();
        System.out.println("jni修改后属性值为field="+jniTest.field);

    }

打印结果

jni修改前属性值为field=yeliang
jni修改后属性值为field=super yeliang

2 C访问Java静态成员变量

c代码

JNIEXPORT void JNICALL Java_com_yeliang_JniTest_accessStaticField(JNIEnv *env, jobject jobj){

    //1 根据jobject获得jclass  
    jclass cls = (*env)->GetObjectClass(env,jobj);

    //2 获得jfieldID
    jfieldID fieldId = (*env)->GetStaticFieldID(env,cls,"count","I");

    //3 GetStatic<Type>Field
    jint count = (*env)->GetStaticIntField(env,cls,fieldId);
    count++;

    //4 修改
    (*env)->SetStaticIntField(env,cls,fieldId,count);
};

java代码

public native String accessStaticField();

private static int count = 5;

public static void main(String[] args) {
        JniTest jniTest = new JniTest();

        System.out.println("jni修改前属性值为count = "+jniTest.count);
        jniTest.accessStaticField();
        System.out.println("jni修改后属性值为count = "+jniTest.count);
    }

打印结果

jni修改前属性值为count = 5
jni修改后属性值为count = 6

3 C访问java方法

c代码

JNIEXPORT void JNICALL Java_com_yeliang_JniTest_accessMethod
(JNIEnv *env, jobject jobj){
    //1 获取jclass  类似java中的反射
    jclass cls = (*env)->GetObjectClass(env,jobj);

    //2 根据方法名和参数找到jmethodID                                  
    jmethodID mid = (*env)->GetMethodID(env,cls,"getRandomInt","(I)I");

    //3 调用java中的方法
    jint random = (*env)->CallIntMethod(env,jobj,mid,200);
    printf("random num:%ld",random);
};

其中的

jmethodID mid = (*env)->GetMethodID(env,cls,"getRandomInt","(I)I");

中的I表示数据类型的签名
数据类型对应的签名是
这里写图片描述

java代码

public native void accessMethod();

public static void main(String[] args) {
        JniTest jniTest = new JniTest();
        jniTest.accessMethod();
    }

    public int getRandomInt(int range){
        System.out.println("Java中的方法执行了");
        return new Random().nextInt(range);

    }

打印结果

Java中的方法执行了
random num:163

4 C访问java静态方法
c代码

JNIEXPORT void JNICALL Java_com_yeliang_JniTest_accessStaticMethod(JNIEnv *env, jobject jobj){
    //1 jclass
    jclass cls = (*env)->GetObjectClass(env,jobj);

    //2 jmethodID
    jmethodID mid = (*env)->GetStaticMethodID(env, cls, "getUUID", "()Ljava/lang/String;");

    //3 调用java方法
    jstring uuid = (*env)->CallStaticObjectMethod(env,cls,mid);

    //4 接收java方法返回的uuid字符串
    char *uuid_str = (*env)->GetStringUTFChars(env,uuid,JNI_FALSE);

    //5 字符串拼接 获得文件名
    char filename[100];
    sprintf(filename,"D://%s.txt",uuid_str);

    FILE *fp = fopen(filename,"w");
    //6 字文件中写入数据
    fputs("to be number one",fp);
    fclose(fp);
};

java代码

public native  void accessStaticMethod();

public static void main(String[] args) {
        JniTest jniTest = new JniTest();
        jniTest.accessStaticMethod();
    }

public static String getUUID(){
        System.out.println("Java中的方法执行了");
        return UUID.randomUUID().toString();
    }

打印结果:

Java中的方法执行了

并在D盘中生成了文件:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值