数据类型,签名,Native层构建java对象,指针常量和常量指针
知识点:
1. 调用 java 层 static 的获取 uuid 的方法
JNIEXPORT void JNICALL Java_com_east_jni08_Sample1_callStaticMethod
(JNIEnv* env,jclass jclz){
// 2. 获取jmethodID
jmethodID j_mid = (*env)->GetStaticMethodID(env, jclz, "getUUID", "()Ljava/lang/String;");
// 1. 调用 getUUID 的方法 statics
jstring j_uuid = (*env)->CallStaticObjectMethod(env,jclz,j_mid);
// jstring -> c_str
char* c_uuid = (*env)->GetStringUTFChars(env,j_uuid,NULL);
// 回收,字符串回收
(*env)->ReleaseStringChars(env,j_uuid,c_uuid);
printf("c_uuid = %s",c_uuid);
}
Jni 回收内存:
(*env)->ReleaseStringUTFChars(env,j_uuid,c_uuid);
2. jni 数据类型
- jstring -> java String
- jint -> java int
- jfloat -> java float
- jdouble -> java double
- jobject -> java object
- jintArray -> java int[]
- jdoubleArray -> java double[]
- jbyteArray -> java byte[]
…
3.java数据类型对应的签名
3.1.基本数据类型签名
- boolean -> Z
- byte -> B
- char -> C
- short -> S
- int -> I
- long -> J
- float -> F
- double -> D
- void -> V
3.2.数组引用类型签名
- int[] -> [I
- float[] -> [f
- byte[] -> [B
- char[] -> [C
- short[] -> [S
- double[] -> [D
- long[] -> [F
- boolean[]-> [Z
3.3.引用数据类型签名
- String -> Ljava/lang/String;
- Object[] -> [L全类名;
4. 常量指针和指针常量
- 常量变量:被常量修饰的变量,不能再次被赋值 (Java)
- 常量指针:const 在 * 之前,指针的地址是可以被再次赋值的(可以修改的),指针地址上面的值(变量)是不能被修改的,常量指针的常量是不能被改变的。
- 指针常量:const 在 * 之后,指针的地址是不可以被再次赋值的(不可以修改的),指针地址上面的值(变量)能被修改的,指针常量的指针地址是不能被改变的。
void main(){
// 常量,不能去修改
const int number = 100;
// number = 200;
int number1 = 100;
int number2 = 200;
// 常量指针(const 在 * 之前,地址可以被重新赋值,但是值不能改变)
// int const * n_p = &number2;
// n_p = &number1;
// printf("n_p = %p",n_p); // 地址是可以重新被赋值的
// *n_p = 300; // 值不能改变
// 指针常量(const 在 * 之后,地址不可以被重新赋值,但是值可以改变)
int* const n_p = &number2;
// n_p = &number1; // 地址是不能被重新赋值的
*n_p = 300;
printf("number2 = %d",number2);// 300
getchar();
}
5. Native 层构建 Java 对象
- 如果是一个类的构造方法获取jmethodID时,名字传
<init>
// c 层 创建 java 对象
JNIEXPORT jobject JNICALL Java_com_east_jni08_Sample1_createPoint
(JNIEnv* env, jclass jclz){
// 2. 需要获取 Point 的class name = "全类名"
// 方法参数上的 jclz 指的是 Sample1.class
jclass point_clz = (*env)->FindClass(env,"com/east/jni08/Point");
// 3. 获取jmethodID ,构造方法写死 "<init>"
jmethodID j_mid = (*env)->GetMethodID(env, point_clz, "<init>","(II)V");
// 1. 创建对象
jobject point = (*env)->NewObject(env,point_clz, j_mid, 11, 12);
// 练习下 y 重新赋值,调用 set 方法
j_mid = (*env)->GetMethodID(env,point_clz,"setY","(I)V");
/* va_list 集合
void (JNICALL *CallVoidMethodV)
(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
// jvalue
void (JNICALL *CallVoidMethodA)
(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args);
*/
(*env)->CallObjectMethod(env,point,j_mid,33);
// 直接重新赋值,相当于反射了但是比反射快
jfieldID j_fid = (*env)->GetFieldID(env,point_clz,"y","I");
(*env)->SetIntField(env,point,j_fid,55);
return point;
}