JNI:02.数据类型,签名,Native层构建java对象,指针常量和常量指针

代码请看:08.JNI基础-Native层构建java对象

1. 调用 java 层 static 的获取 uuid 的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 在 * 之后,指针的地址是不可以被再次赋值的(不可以修改的),指针地址上面的值(变量)能被修改的,指针常量的指针地址是不能被改变的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 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;
}
-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!
0%