JNI笔记 C访问Java构造方法,父类方法,中文乱码,C向Java中传入数组
来源:互联网 发布:陈忠徐紫砂壶淘宝假货 编辑:程序博客网 时间:2024/05/20 10:51
1 访问构造方法
c代码
JNIEXPORT jobject JNICALL Java_com_yeliang_JniTest_accessConstructor(JNIEnv *env, jobject jobj){ //1 根据全类名 找到jclass jclass cls = (*env)->FindClass(env,"java/util/Date"); //2 jmethodID jmethodID construct_mid = (*env)->GetMethodID(env,cls,"<init>","()V"); //3 实例化一个Date对象 jobject date_obj = (*env)->NewObject(env,cls,construct_mid); //4 找到getTime)()方法 jmethodID mid = (*env)->GetMethodID(env,cls,"getTime","()J"); //4 调用对象中的方法 jlong time = (*env)->CallLongMethod(env,date_obj,mid); printf("time:%lld\n",time); return date_obj;}
找到方法对应的签名: 配置了环境变量后 使用如下命令 javap -p -s 全类名
java代码
public native Date accessConstructor();public static void main(String[] args) { JniTest jniTest = new JniTest(); jniTest.accessConstructor(); }
2 调用父类的方法
c代码
JNIEXPORT void JNICALL Java_com_yeliang_JniTest_accessNonvirtualMethod(JNIEnv *env, jobject jobj){ //1 jclass jclass cls = (*env)->GetObjectClass(env,jobj); //2 获取Man对象(对象) jfieldID fid = (*env)->GetFieldID(env, cls, "human", "Lcom/yeliang/Human;"); //3 jobject jobject human_obj = (*env)->GetObjectField(env,jobj,fid); //4 Human类 jclass jclass human_cls = (*env)->FindClass(env,"com/yeliang/Human"); //5 jmethidID 执行sayHi方法 jmethodID mid = (*env)->GetMethodID(env,human_cls,"sayHi","()V"); //6 调用父类的方法 (*env)->CallNonvirtualObjectMethod(env,human_obj,human_cls,mid);}
查看方法签名的方法
java代码
public class Human { public void sayHi(){ System.out.println("hello i am human"); }}
public class Man extends Human { public void sayHi() { System.out.println("hi i am man"); }}
打印结果
hello i am human
3 中文乱码问题
c代码
JNIEXPORT jstring JNICALL Java_com_yeliang_JniTest_accessChineseChar(JNIEnv *env, jobject jobj, jstring str){ //输出 char *c_str = (*env)->GetStringUTFChars(env,str,JNI_FALSE); printf("%s\n",c_str);}
java代码
public native void accessChineseChar(String string);public static void main(String[] args) { JniTest jniTest = new JniTest(); jniTest.accessChineseChar("德玛西亚必胜!"); }
打印结果
寰风帥瑗夸簹蹇呰儨锛?
修改后 把字符串从java传到c,在从c中传到java
c代码
JNIEXPORT jstring JNICALL Java_com_yeliang_JniTest_accessChineseChar(JNIEnv *env, jobject jobj,jstring jstr){ //输出 /*char *c_str = (*env)->GetStringUTFChars(env,str,JNI_FALSE); printf("%s\n",c_str);*/ char *c_str = (*env)->GetStringUTFChars(env,jstr,JNI_FALSE); //char *c_str = "德玛西亚必胜!"; //2 jclass-->String类 jclass str_cls = (*env)->FindClass(env, "java/lang/String"); //3 构造方法 jmethodID jmethodID construct_mid = (*env)->GetMethodID(env, str_cls, "<init>", "([BLjava/lang/String;)V"); //4 jbyteArray jbyteArray bytes = (*env)->NewByteArray(env, strlen(c_str)); //bytes赋值 (*env)->SetByteArrayRegion(env, bytes, 0, strlen(c_str), c_str); //6 编码格式 jstring jstring charsetName = (*env)->NewStringUTF(env, "UTF-8"); //7 调用构造函数,返回编码之后的jstring return (*env)->NewObject(env, str_cls, construct_mid, bytes, charsetName);}
java代码不变
打印结果
德玛西亚必胜!
上面是把字符串从java中传到c中,在从c中传到java的过程。主要是利用在c中调用java中String的构造方法来完成字符格式的转换
public String(byte bytes[], String charsetName) throws UnsupportedEncodingException { this(bytes, 0, bytes.length, charsetName); }
直接把c中字符串传到java
JNIEXPORT jstring JNICALL Java_com_yeliang_JniTest_accessChineseChar(JNIEnv *env, jobject jobj,jstring jstr){ //输出 /*char *c_str = (*env)->GetStringUTFChars(env,str,JNI_FALSE); printf("%s\n",c_str);*/ //char *c_str = (*env)->GetStringUTFChars(env,jstr,JNI_FALSE); char *c_str = "德玛西亚必胜!"; //2 jclass-->String类 jclass str_cls = (*env)->FindClass(env, "java/lang/String"); //3 构造方法 jmethodID jmethodID construct_mid = (*env)->GetMethodID(env, str_cls, "<init>", "([BLjava/lang/String;)V"); //4 jbyteArray jbyteArray bytes = (*env)->NewByteArray(env, strlen(c_str)); //bytes赋值 (*env)->SetByteArrayRegion(env, bytes, 0, strlen(c_str), c_str); //6 编码格式 jstring jstring charsetName = (*env)->NewStringUTF(env, "GB2312"); //7 调用构造函数,返回编码之后的jstring return (*env)->NewObject(env, str_cls, construct_mid, bytes, charsetName);}
打印结果
德玛西亚必胜!
这此时在c中定义的char* str。然后传到java中。并改了字符编码格式。
4 把数组从java传到c中
c代码
int compare(int *a, int *b){ return (*a) - (*b);}JNIEXPORT void JNICALL Java_com_yeliang_JniTest_passArray(JNIEnv *env, jobject jobj, jintArray arr){ //1 jintArray ->jint指针 -> c int数组 jint *elems = (*env)->GetIntArrayElements(env,arr,NULL); //2 数组的长度 int len = (*env)->GetArrayLength(env,arr); //3 排序 qsort(elems,len,sizeof(jint),compare); //4 同步 (*env)->ReleaseIntArrayElements(env,arr,elems,JNI_COMMIT);}
java代码
public static void main(String[] args) { JniTest jniTest = new JniTest(); int [] array = {1,2,4,2,5}; jniTest.passArray(array); for(int i=0;i<array.length;i++){ System.out.println(array[i]); } }
打印结果
1 2 2 4 5
4 把数组从java传到c中
c代码
JNIEXPORT jarray JNICALL Java_com_yeliang_JniTest_getArray(JNIEnv *env, jobject jobj, jint len){ //1 创建一个指定大小的数组 jintArray jint_arr = (*env)->NewIntArray(env,len); //2 jintArray ->jint指针 -> c int数组 jint *elems = (*env)->GetIntArrayElements(env,jint_arr,NULL); int i = 0; for (; i < len;i++){ elems[i] = i; } //3 同步 //0 , java数组进行更新,并且释放c/c++数组 //JNI_ABORT java数组不进行更新,但是释放c/c++数组 //JNI_CoMMIT, java数组进行更新,不释放c/c++数组(函数执行完 数组还是会释放) (*env)->ReleaseIntArrayElements(env,jint_arr,elems,0); return jint_arr;}
java代码
public native int[] getArray(int size);public static void main(String[] args) { JniTest jniTest = new JniTest(); int [] array = jniTest.getArray(8); for(int i=0;i<array.length;i++){ System.out.println(array[i]); } }
打印结果
0 1 2 3 4 5 6 7
阅读全文
0 0
- JNI笔记 C访问Java构造方法,父类方法,中文乱码,C向Java中传入数组
- JNI笔记 C访问java属性方法
- Jni基础(二) C语言访问Java构造方法,父类方法
- JNI(C访问Java方法)
- JNI访问Java数组方法
- JNI中C调用Java方法
- JNI中C调用Java方法
- JNI中C调用Java方法
- JNI中C调用Java方法
- JNI中C调用Java方法
- JNI中JAVA调用C/C++方法
- JNI中C调用Java方法
- JNI中C调用Java方法
- JNI中C调用Java方法
- Android JNI中C调用Java方法
- JNI中C回调java方法
- JNI中C调用Java方法
- Ndk学习之JNI传入数组(java-->C)
- 百度地图Marker隐藏/显示
- IO流中write()和writeShort()的小坑
- QTimer::singleShot()函数使用
- PHP面试题整理
- js判断识别微信或QQ浏览器
- JNI笔记 C访问Java构造方法,父类方法,中文乱码,C向Java中传入数组
- 四大机器学习降维算法:PCA、LDA、LLE、Laplacian Eigenmaps
- 写作建议
- 【R语言 社交网络】R语言关系网络图+ PageRank算法实现
- 微信支付遇到的坑
- 2017年5月iOS招人心得(附面试题)
- hdu5520 最小费用最大流
- Hi3516a (4) make OSDRV_CROSS=arm-hisiv300-linux all
- 从字符串中获取最长子串的长度