|
@@ -0,0 +1,92 @@
|
|
|
|
|
+#include "space_anyi_jni_parameter_ObjectTest.h"
|
|
|
|
|
+JNIEXPORT jobject JNICALL Java_space_anyi_jni_parameter_ObjectTest_getStudent(JNIEnv *env, jobject this){
|
|
|
|
|
+ printf("start:getStudent\n");
|
|
|
|
|
+ //C语言与C++语言使用env指针的方式不一样,C语言比C++语言版本的api多一对小括号和多传递一个参数
|
|
|
|
|
+ //C语言:(*env)->functionName(env,args...)
|
|
|
|
|
+ //C++语言:env->functionName(args...)
|
|
|
|
|
+ //1.通过JNIEnv指针获取指定类的jclass,通过类的类型签名指定
|
|
|
|
|
+ jclass class_Student = (*env)->FindClass(env,"Lspace/anyi/jni/parameter/Student;");
|
|
|
|
|
+ //2.获取类的构造方法,第一个参数是类的jclass,第二个参数是方法名,第三个参数是方法的类型签名
|
|
|
|
|
+ //构造方法的名称为:<init>,构造方法的返回值为void
|
|
|
|
|
+ jmethodID method_constructor_Student = (*env)->GetMethodID(env,class_Student,"<init>","(Ljava/lang/String;)V");
|
|
|
|
|
+ //3.调用构造方法创建对象,第一个参数是类的jclass,第二参数为jmethodID,从第三个参数开始为方法的入参
|
|
|
|
|
+ jstring nameStr = (*env)->NewStringUTF(env, "yangyi");
|
|
|
|
|
+ jobject student = (*env)->NewObject(env,class_Student,method_constructor_Student,nameStr);
|
|
|
|
|
+ //4.获取类的普通方法,第一个参数是jclass,第二个参数是方法的名称,第三个参数方法的类型签名
|
|
|
|
|
+ jmethodID student_method_setAge = (*env)->GetMethodID(env,class_Student,"setAge","(I)V");
|
|
|
|
|
+ //5.调用类的普通方法,第一个参数是将要调用该方法实例对象的jobject,第二个参数是方法对应的jmethodID,从第三个参数开始为方法的入参
|
|
|
|
|
+ (*env)->CallObjectMethod(env,student,student_method_setAge,18);
|
|
|
|
|
+ //6.获取类的普通字段,第一个参数是类的jcalss,第二个参数是字段的名称,第三个参数是字段的类型签名
|
|
|
|
|
+ jfieldID student_field_height = (*env)->GetFieldID(env,class_Student,"height","F");
|
|
|
|
|
+ //7.给类的普通字段设置值,第一个参数是类实例对应的jobject,第二个参数是字段对应的jfieldID,第三个参数是要设置的目标值
|
|
|
|
|
+ (*env)->SetFloatField(env,student,student_field_height,1.66);
|
|
|
|
|
+ //8.释放局部引用资源
|
|
|
|
|
+ (*env)->DeleteLocalRef(env, class_Student);
|
|
|
|
|
+ //创建JNI全局引用,以便JVM可以使用JNI中创建的对象
|
|
|
|
|
+ jobject result = (*env)->NewGlobalRef(env,student);
|
|
|
|
|
+ printf("end:getStudent\n");
|
|
|
|
|
+ return result;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+JNIEXPORT void JNICALL Java_space_anyi_jni_parameter_ObjectTest_printStudentInfo(JNIEnv *env, jobject this, jobject student){
|
|
|
|
|
+ printf("start:printStudentInfo\n");
|
|
|
|
|
+ //1.调用对象的普通方法
|
|
|
|
|
+ //1.1获取jclass
|
|
|
|
|
+ jclass class_Student = (*env)->GetObjectClass(env,student);
|
|
|
|
|
+ //1.2获取jmethodID
|
|
|
|
|
+ jmethodID student_method_info = (*env)->GetMethodID(env,class_Student,"info","()V");
|
|
|
|
|
+ //1.3call
|
|
|
|
|
+ (*env)->CallObjectMethod(env,student,student_method_info);
|
|
|
|
|
+ //2.获取对象的字段值
|
|
|
|
|
+ //2.1获取jfieldID
|
|
|
|
|
+ jfieldID student_field_height = (*env)->GetFieldID(env,class_Student,"height","F");
|
|
|
|
|
+ //2.2获取对象字段对应的值
|
|
|
|
|
+ jfloat height = (*env)->GetFloatField(env,student,student_field_height);
|
|
|
|
|
+ printf("height:%f\n",height);
|
|
|
|
|
+ //基本类型的数组操作
|
|
|
|
|
+ //3.1创建数组
|
|
|
|
|
+ jint size = 3;
|
|
|
|
|
+ jintArray newArray = (*env)->NewIntArray(env, size);
|
|
|
|
|
+ //3.2设置数组中的值
|
|
|
|
|
+ //第一个参数为数组的jarray,第二个参数为数组的默认值
|
|
|
|
|
+ jint *source = (*env)->GetIntArrayElements(env, newArray, NULL);
|
|
|
|
|
+ source[0] = 90;
|
|
|
|
|
+ source[1] = 91;
|
|
|
|
|
+ source[2] = 92;
|
|
|
|
|
+ //3.3获取数组中的值
|
|
|
|
|
+ jint val1 = source[0];
|
|
|
|
|
+ jint val2 = source[1];
|
|
|
|
|
+ jint val3 = source[2];
|
|
|
|
|
+ //更新数组的修改,第一个参数为数组的jarray,第二个参数为C/C++中数组,第三个参数为模式(0:将数组拷贝到jarray并释放C/C++中数组的内存;1:拷贝数组但不释放内存;2:不拷贝但释放内存)
|
|
|
|
|
+ (*env)->ReleaseIntArrayElements(env, newArray, source,0);
|
|
|
|
|
+ //获取数组的长度
|
|
|
|
|
+ jsize length = (*env)->GetArrayLength(env, newArray);
|
|
|
|
|
+ jfieldID student_field_source = (*env)->GetFieldID(env,class_Student,"source","[I");
|
|
|
|
|
+ (*env)->SetObjectField(env,student,student_field_source,newArray);
|
|
|
|
|
+ //对象类型的数组操作
|
|
|
|
|
+ jclass class_String = (*env)->FindClass(env,"Ljava/lang/String;");
|
|
|
|
|
+ //第一个参数为数组的大小,第二个参数为对象的jclass,第三个参数为数组默认值
|
|
|
|
|
+ jobjectArray objectArray = (*env)->NewObjectArray(env, size,class_String,NULL);
|
|
|
|
|
+ //对象数组赋值
|
|
|
|
|
+ jint index = 0;
|
|
|
|
|
+ jstring hobby = (*env)->NewStringUTF(env,"学习");
|
|
|
|
|
+ //第一个参数为jarray,第二个参数为索引,第三个参数为值的jobject
|
|
|
|
|
+ (*env)->SetObjectArrayElement(env,objectArray,index,hobby);
|
|
|
|
|
+ //对象数组取值,第一个参数为jarray,第二个参数为索引
|
|
|
|
|
+ jobject value = (*env)->GetObjectArrayElement(env,objectArray,index);
|
|
|
|
|
+ jfieldID student_field_hobby = (*env)->GetFieldID(env,class_Student,"hobby","[Ljava/lang/String;");
|
|
|
|
|
+ (*env)->SetObjectField(env,student,student_field_hobby,objectArray);
|
|
|
|
|
+ //释放局部引用资源,可选
|
|
|
|
|
+ (*env)->DeleteLocalRef(env, class_Student);
|
|
|
|
|
+ printf("end:printStudentInfo\n");
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+JNIEXPORT void JNICALL Java_space_anyi_jni_parameter_ObjectTest_free(JNIEnv *env, jobject this, jobject student){
|
|
|
|
|
+ printf("start:free\n");
|
|
|
|
|
+ if(student != NULL){
|
|
|
|
|
+ printf("释放全局引用\n");
|
|
|
|
|
+ (*env)->DeleteGlobalRef(env,student);
|
|
|
|
|
+ }
|
|
|
|
|
+ printf("end:free\n");
|
|
|
|
|
+}
|