您的位置:首页 > 其它

JNI的初步使用(二)

2017-03-27 10:03 225 查看
JNI基本数据类型,以及C,C++访问Java

Java代码,获取类的属性和静态属性,以及java的函数,构造方法,传入数组并排序,以及返回一个数组

public class JniTest {
public String key="jason";

public native static void getStringFromC();

//访问属性,返回修改之后的属性内容
public native String accessfield();

public static void main(String[] args){
JniTest t=new JniTest();
System.out.println(t.accessfield());

}
//加载动态库
static{
System.loadLibrary("jni_study");
}

}


.c文件

//每个native函数,都至少有两个参数(JNIEnv*,jclass或者jobject)
//1)当native方法为静态方法时:
//jclass 代表native方法所属类的class对象(JniTest.class)
//2)当native方法为非静态方法时:
//jobject 代表native方法所属的对象

//基本数据
//Java基本数据类型与JNI数据类型的映射关系
//Java类型->JNI类型->C类型

/*
boolean jboolean
byte jbyte;
char jchar;
short jshort;
int jint;
long jlong;
float jfloat;
double jdouble;
void void
*/

//引用类型(对象)
//String jstring
//object jobject
//数组,基本数据类型的数组
//byte[] jByteArray
//对象数组
//object[](String[]) jobjectArray

//修改属性key
JNIEXPORT jstring JNICALL Java_com_skyl_jni_JniTest_accessField
(JNIEnv *env, jobject jobj){
//jobj是t对象,JniTest.class
jclass cls = (*env)->GetObjectClass(env, jobj);
//jfieldID
//属性名称,属性签名
jfieldID fid = (*env)->GetFieldID(env, cls, "key", "Ljava/lang/String;");

//jason >> super jason
//获取key属性的值
//Get<Type>Field
jstring jstr = (*env)->GetObjectField(env, jobj, fid);
printf("jstr:%#x\n",&jstr);

//jstring -> c字符串
//isCopy 是否复制(true代表赋值,false不复制)
char *c_str = (*env)->GetStringUTFChars(env,jstr,JNI_FALSE);
//拼接得到新的字符串
char text[20] = "super ";
strcat(text,c_str);

//c字符串 ->jstring
jstring new_jstr = (*env)->NewStringUTF(env, text);

//修改key
//Set<Type>Field
(*env)->SetObjectField(env, jobj, fid, new_jstr);

printf("new_jstr:%#x\n", &new_jstr);

return new_jstr;
}


访问静态属性

JNIEXPORT void JNICALL Java_com_skyl_jni_JniTest_accessStaticField
(JNIEnv *env, jobject jobj){
//jclass
jclass cls = (*env)->GetObjectClass(env, jobj);
//jfieldID
jfieldID fid = (*env)->GetStaticFieldID(env, cls, "count", "I");
//GetStatic<Type>Field
jint count = (*env)->GetStaticIntField(env, cls, fid);
count++;
//修改
//SetStatic<Type>Field
(*env)->SetStaticIntField(env,cls,fid,count);
}


2.访问java方法

JNIEXPORT void JNICALL Java_com_dongnaoedu_jni_JniTest_accessMethod
(JNIEnv *env, jobject jobj){
//jclass
jclass cls = (*env)->GetObjectClass(env, jobj);
//jmethodID
jmethodID mid = (*env)->GetMethodID(env, cls, "genRandomInt", "(I)I");
//调用
//Call<Type>Method
jint random = (*env)->CallIntMethod(env, jobj, mid, 200);
printf("random num:%ld",random);

//.....
}


静态方法

JNIEXPORT void JNICALL Java_com_skyl_jni_JniTest_accessStaticMethod
(JNIEnv *env, jobject jobj){
//jclass
jclass cls = (*env)->GetObjectClass(env, jobj);
//jmethodID
jmethodID mid = (*env)->GetStaticMethodID(env, cls, "getUUID", "()Ljava/lang/String;");

//调用
//CallStatic<Type>Method
jstring uuid = (*env)->CallStaticObjectMethod(env, cls, mid);

//随机文件名称 uuid.txt
//jstring -> char*
//isCopy JNI_FALSE,代表java和c操作的是同一个字符串
char *uuid_str = (*env)->GetStringUTFChars(env, uuid, JNI_FALSE);
//拼接
char filename[100];
sprintf(filename, "D://%s.txt",uuid_str);
FILE *fp = fopen(filename,"w");
fputs("i love jason", fp);
fclose(fp);
}


访问构造方法

//使用java.util.Date产生一个当前的时间戳
JNIEXPORT jobject JNICALL Java_com_skyl_jni_JniTest_accessConstructor
(JNIEnv *env, jobject jobj){
jclass cls = (*env)->FindClass(env, "java/util/Date");
//jmethodID
jmethodID constructor_mid = (*env)->GetMethodID(env, cls, "<init>", "()V");
//实例化一个Date对象
jobject date_obj = (*env)->NewObject(env, cls, constructor_mid);
//调用getTime方法
jmethodID mid = (*env)->GetMethodID(env, cls, "getTime", "()J");
jlong time = (*env)->CallLongMethod(env, date_obj, mid);

printf("\ntime:%lld\n",time);

return date_obj;
}


传入数组并排序

JNIEXPORT void JNICALL Java_com_skyl_jni_JniTest_giveArray
(JNIEnv *env, jobject jobj, jintArray arr){
//jintArray -> jint指针 -> c int 数组
jint *elems = (*env)->GetIntArrayElements(env, arr, NULL);
//printf("%#x,%#x\n", &elems, &arr);

//数组的长度
int len = (*env)->GetArrayLength(env, arr);
//排序
qsort(elems, len, sizeof(jint), compare);

//同步
(*env)->ReleaseIntArrayElements(env, arr, elems, JNI_COMMIT);
}


返回一个数组

JNIEXPORT jintArray JNICALL Java_com_skyl_jni_JniTest_getArray(JNIEnv *env, jobject jobj, jint len){
//创建一个指定大小的数组
jintArray jint_arr = (*env)->NewIntArray(env, len);
jint *elems = (*env)->GetIntArrayElements(env, jint_arr, NULL);
int i = 0;
for (; i < len; i++){
elems[i] = i;
}

//同步
(*env)->ReleaseIntArrayElements(env, jint_arr, elems, 0);

return jint_arr;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: