[toc]
为啥呢
jni环境终于搞完了,也进行了实际操作一波. 但是还是想玩更深的呀; 否则光来基础有何用呢. 该浪的就要浪呀
jni 数据类型
- 基础数据类型和java对应的
jshort s, jint i, jlong l, jfloat f,
jdouble d, jchar c, jboolean z, jbyte b, - 引用的数据类型
jstring j_str
jclass: java的字节码对象
jarray :数组 而且还派生了8个基本数据类型的数组 jintArray,jlongArray
当使用javah 时会生成这个函数的参数
字符串处理
因为 Java 默认使用 Unicode 编码,而 C/C++ 默认使用 UTF 编码,所以在本地代码中操作字符串的时候,必须使用合适的 JNI 函数把 jstring 转换成 C 风格的字符串。JNI 支持字符串在 Unicode 和 UTF-8 两种编码之间转换,
字符串utf,unicodeconst char c_str = NULL;
c_str = (env)->GetStringUTFChars(env, j_str, &isCopy);
– env: JNIEnv 函数表的指针
– j_str: 是传过来的字符串指针
– idCopy,取值 JNI_TRUE 和 JNI_FALSE,如果值为 JNI_TRUE,表示返回 JVM 内部源字符串的一份拷贝,并为新产生的字符串分配内存空间。如果值为 JNI_FALSE,表示返回 JVM 内部源字符串的指针,意味着可以通过指针修改源字符串的内容(就是c的指针,但是java字符串是不允许修改的,修改会从新生成一个string,这样违背了java的思想);
创建字符串:(*env)->NewStringUTF(env,buff);
数组
jint *c_array;
jint arr_len;
//1. 获取数组长度
arr_len = (*env)->GetArrayLength(env,j_array);
//2. 根据数组长度和数组元素的数据类型申请存放java数组元素的缓冲区
c_array = (jint*)malloc(sizeof(jint) * arr_len);
//3. 初始化缓冲区
memset(c_array,0,sizeof(jint)*arr_len);
printf("arr_len = %d ", arr_len);
//4. 拷贝Java数组中的所有元素到缓冲区中
(*env)->GetIntArrayRegion(env,j_array,0,arr_len,c_array);
for (i = 0; i < arr_len; i++) {
sum += c_array[i]; //5. 累加数组元素的和
}
free(c_array); //6. 释放存储数组元素的缓冲区
c/c++ 访问java方法
其实这个没有什么用,毕竟用到c的地方java真的没有什么事情了.毕竟c/c++这么难开发,都用它俩开发了肯定还能重写一下调用的java的逻辑代码呀;
就是刚才的 (*env)->方法名 调用,原则是在java那边
大致过程和反射机制其实差不多;
// 1、从classpath路径下搜索ClassMethod这个类,并返回该类的Class对象
clazz =(*env)->FindClass(env,"com/study/jnilearn/ClassMethod");
if (clazz == NULL) {
return;
}
// 2、从clazz类中查找callStaticMethod方法
mid_static_method = (*env)->GetStaticMethodID(env,clazz,"callStaticMethod","(Ljava/lang/String;I)V");
if (mid_static_method == NULL) {
printf("找不到callStaticMethod这个静态方法。");
return;
}
// 3、调用clazz类的callStaticMethod静态方法
str_arg = (*env)->NewStringUTF(env,"我是静态方法");
(*env)->CallStaticVoidMethod(env,clazz,mid_static_method, str_arg, 100);
发表回复