JNI之c调用java的函数,调用java的构造生成对象,得到java的成员,以及C返回Java字符串乱码

#define _CRT_SECURE_NO_WARNINGS




#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "com_fourlm_jnitest_JniTest.h"


//访问成员属性,并且修改
JNIEXPORT jstring JNICALL Java_com_fourlm_jnitest_JniTest_accessField
(JNIEnv *env, jobject obj){


//obj是t对象,JNITest.class
jclass cls = (*env)->GetObjectClass(env,obj);
//jfieldID
//第一个是env。第二个是cls,第三个是属性名称,第四个是属性签名,一定要有,可以使用javap生成
jfieldID fid = (*env)->GetFieldID(env, cls, "key", "Ljava/lang/String;");
//fourlm 变成super fourlm,
//获取了key属性的值
jstring jstr = (*env)->GetObjectField(env,obj,fid);
//jstring -> c的字符串
//第三个参数的含义.iscopy 是否複製的意思,一般写NULL
char *c_str = (*env)->GetStringUTFChars(env,jstr,NULL);
//拼接得到新的字符串是
char text[20] = "super";
strcat(text,c_str);

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


//修改key
(*env)->SetObjectField(env,obj,fid,new_jstr);

return new_jstr;
};


//访问静态属性
JNIEXPORT void JNICALL Java_com_fourlm_jnitest_JniTest_accessStaticFiel
(JNIEnv * env,jobject obj){
//获取对象的.class
jclass cls  = (*env)->GetObjectClass(env,obj);


//获取属性的fieldID
jfieldID fid = (*env)->GetStaticFieldID(env, cls, "count", "I");
//通过fieldID获取属性
jint count = (*env)->GetStaticIntField(env,cls,fid);


count++;
//重新设置属性
(*env)->SetStaticIntField(env, cls, fid, count);


}


//访问java方法
JNIEXPORT void JNICALL Java_com_fourlm_jnitest_JniTest_accessMethod
(JNIEnv* env,jobject obj){
jclass cls = (*env)->GetObjectClass(env,obj);
//得到方法的ID
jmethodID mid = (*env)->GetMethodID(env,cls,"getRandomInt","(I)I");
//执行该方法Call<Type>Method
jint random = (*env)->CallIntMethod(env,obj,mid ,200);
printf("%ld\n",random);
}


//访问java静态方法
JNIEXPORT void JNICALL Java_com_fourlm_jnitest_JniTest_accessStaticMethod
(JNIEnv* env,jobject obj){
jclass cls = (*env)->GetObjectClass(env,obj);
jmethodID mid = (*env)->GetStaticMethodID(env, cls, "getUUID", "()Ljava/lang/String;");
printf("----------");
jstring uuid = (*env)->CallStaticObjectMethod(env,obj,mid);
char* str = (*env)->GetStringUTFChars(env,uuid,NULL);
printf("%s",str);
}


//访问java构造方法


JNIEXPORT void JNICALL Java_com_fourlm_jnitest_JniTest_accessConstructor
(JNIEnv* env,jobject obj){
jclass cls = (*env) -> FindClass(env,"java/util/Date");
//得到構造函數的MethodID
jmethodID constructorID =  (*env)->GetMethodID(env,cls,"<init>","()V");


//实例化一个Data对象 
jobject dataobj = (*env)->NewObject(env,cls ,constructorID);
//得到getTime方法的ID
jmethodID method_id=(*env)->GetMethodID(env,cls,"getTime","()J");
jlong time = (*env)->CallLongMethod(env,dataobj,method_id);
printf("%ld",time);
}


//调用父类的方法
JNIEXPORT void JNICALL Java_com_fourlm_jnitest_JniTest_accessNonvirtualMethod
(JNIEnv* env,jobject obj){
jclass cls = (*env)->GetObjectClass(env,obj);
//获取man属性(对象)的ID
jfieldID fid = (*env)->GetFieldID(env, cls, "man", "Lcom/fourlm/jnitest/Human;");
//获取man对象
jobject human_obj = (*env)->GetObjectField(env,obj,fid);


//执行human_obj对象的方法
//先找到class,注意,传父类的名称
jclass human_cls= (*env)->FindClass(env,"com/fourlm/jnitest/Human");
//通过class找到human内的sayhi方法的ID
jmethodID humanmethodID = (*env)->GetMethodID(env,human_cls,"sayHi","()V");
//执行该方法,执行当前类实际对象的方法
//(*env)->CallObjectMethod(env,human_obj,humanmethodID);
//调用父类的该方法
(*env)->CallNonvirtualObjectMethod(env,human_obj,human_cls,humanmethodID);
}


//中文乱码问题
JNIEXPORT jstring JNICALL Java_com_fourlm_jnitest_JniTest_chineseChars
(JNIEnv* env,jobject obj){
char *c_str = "哈哈哈哈哈";
jclass str_cls = (*env)->FindClass(env,"java/lang/String");
jmethodID constructor_mid = (*env)->GetMethodID(env, str_cls, "<init>", "([BLjava/lang/String;)V");

//jbyte -> char 
//一个byte对应一个char字符
jbyteArray bytes = (*env)->NewByteArray(env,strlen(c_str));
//对byte数组进行赋值,从cstr赋值到bytes
(*env)->SetByteArrayRegion(env,bytes,0,strlen(c_str),c_str);


//生成一个字符编码的jstring
jstring charsetName = (*env)->NewStringUTF(env,"GB2312");


//调用构造函数,返回编码之后的jstring

return (*env)->NewObject(env,str_cls,constructor_mid,bytes,charsetName);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值