JNI由浅入深_5_基本类型应用

1、基本类型应用

对于JNI处理基本类型还是比较简单的,下面是Java代码:

<span style="font-size:14px;"> public native int intMethod(int n);

 public native boolean booleanMethod(boolean bool);</span>

上面的方法是在Java中写的,注意要加native关键字,这两个方法都比较简单,分别传入int ,boolean类型到jni中,经过处理返回。下面是jni的代码:

<span style="font-size:14px;">JNIEXPORT jint JNICALL Java_com_example_jniandroid_service_SimpleObject_intMethod(
		JNIEnv * env, jobject obj, jint val) {
	return val * val;
}

JNIEXPORT jboolean JNICALL Java_com_example_jniandroid_service_SimpleObject_booleanMethod(
		JNIEnv * env, jobject obj, jboolean val) {
	return !val;
}</span>

2、基本数据类型的数组应用

2.1 c处理Java的int[],并返回该数组元素的总和。

public native int intArrayMethod(int[] intArray);
/**
 * 求数组的和,返回一个int类型
 */
JNIEXPORT jint JNICALL Java_com_example_jniandroid_service_SimpleObject_intArrayMethod(
		JNIEnv * env, jobject obj, jintArray array) {
	int i, sum = 0;
	//获取数组的长度
	jsize len = (*env)->GetArrayLength(env, array);
	//取得数组首地址的指针
	jint *body = (*env)->GetIntArrayElements(env, array, 0);
	for (i = 0; i < len; i++) {
		//获取数组中的元素
		sum += body[i];
	}
	//释放资源
	(*env)->ReleaseIntArrayElements(env, array, body, 0);
	LOGD("数组总和 =%d", sum);
	return sum;
}

2.2 native方法返回一个int[].

public native int[] receiverIntArray();

对应的c签名

/**
 * 返回Java的int[]类型
 */
JNIEXPORT jintArray JNICALL Java_com_example_jniandroid_service_SimpleObject_receiverIntArray(
		JNIEnv * env, jobject obj) {
	int i = 1;
	jintArray array; //定义数组对象
	array = (*env)->NewIntArray(env, 10);
	for (; i <= 10; i++) {
		//void SetIntArrayRegion(jintArray array, jsize start, jsize len,const jint *buf)//  len:为1
		(*env)->SetIntArrayRegion(env, array, i - 1, 1, &i);
	}
	/* 获取数组对象的元素个数 */
	int len = (*env)->GetArrayLength(env, array);
	/* 获取数组中的所有元素 */
	jint* elems = (*env)->GetIntArrayElements(env, array, 0);

	for (i = 0; i < len; i++) {
		LOGD("ELEMENT %d IS %d\n", i, elems[i]);
	}

	return array;

}

3、JNI处理string类型和String数组

	public native String stringMethod(String text);

	public native String[] receiverStringArray(String val);

下面是jni的实现,在c文件的前面声明数组长度 #define ARRAY_LENGTH 5 。第一个方法是将一个字符串中的每个字符转换成大写,第二方法返回一个String类型的数组。这里用到了FindClass方法,它主要根据类的包名找到该类的class,在通过new方法创建对象。

JNIEXPORT jstring JNICALL Java_com_example_jniandroid_service_SimpleObject_stringMethod(
		JNIEnv * env, jobject obj, jstring string) {
	const char *str = (*env)->GetStringUTFChars(env, string, 0);
	char cap[128];
	//copy字符串
	strcpy(cap, str);
	(*env)->ReleaseStringUTFChars(env, string, str);
	int i = 0;
	for (i = 0; i < strlen(cap); i++) {
		//转换成大写
		*(cap + i) = (char) toupper(*(cap + i));
	}
	return (*env)->NewStringUTF(env, cap);

}

/**
 * 返回Java字符串数组
 */
JNIEXPORT jobjectArray JNICALL Java_com_example_jniandroid_service_SimpleObject_receiverStringArray(
		JNIEnv * env, jobject obj, jstring val) {
	//FindClass找到Java中String这个类,返回jni的jclass对象
	jclass objClass = (*env)->FindClass(env, "java/lang/String");
	//NewObjectArray创建对象数组,第二个参数长度,第三个类型
	jobjectArray texts = (*env)->NewObjectArray(env, (jsize) ARRAY_LENGTH,objClass, 0);
	jstring jstr;
	char* sa[] = { "Hello,", "world", "jni", "iii", "爱死你了" };
	int i = 0;
	for (; i < ARRAY_LENGTH; i++) {
		//创建jstring并赋值,NewStringUTF()函数将C语言的字符串转换为jstring类型
		jstr = (*env)->NewStringUTF(env, sa[i]);
		//赋值
		(*env)->SetObjectArrayElement(env, texts, i, jstr); //必须放入jstring
	}
	return texts;

}
时间: 2024-08-13 07:18:43

JNI由浅入深_5_基本类型应用的相关文章

JNI由浅入深_3_Hello World

1.需要准备的工具,eclipse,cdt(c++)插件,cygwin(unix)和 android ndk. 在cygwin的etc目录下将ndk的路径引入到profile文件中,可以在cygwin的任何目录都可以访问到ndk,不同的ndk路径PATH的写法不同. : ${ORIGINAL_PATH=${PATH}} if [ ${CYGWIN_NOWINPATH-addwinpath} = "addwinpath" ] ; then PATH="/usr/local/bi

JNI由浅入深_6_简单对象的应用

1.声明native方法 public class ComplexObject { /** * 返回一个对象数组 * @param val * @return */ public native Person[] receiverBeanArray(String val); /** * 获取对象 * @return */ public native Person getPerson(); /** * 获取对象的集合 * @return */ public native ArrayList<Pers

JNI由浅入深_9_JNI 异常处理

1 .本地代码中如何缓存和抛出异常 下面的代码中演示了如何声明一个会抛出异常的本地方法.CatchThrow这个类声明了一个会抛出IllegalArgumentException异常的名叫doit的本地方法. <span style="font-family:Comic Sans MS;font-size:14px;">class CatchThrow { private native void doit() throws IllegalArgumentException;

JNI由浅入深_7_c调用Java方法一

1.在Java中声明方法 <span style="font-size:14px;">/** * javah -encoding utf-8 -jni com.example.jniandroid.service.CFunction * 当java中有中文时,会报编码GBK不可映射字符 方法的调用,加上-encoding utf-8 * * @author libin * */ public class CFunction { /** * 实现在c里面回调callback方

JNI由浅入深_10_JNI 综合开发

1.使用ndk-build时如果找不到某个类,可以使用下面两种方法解决: 1.1 进入src目录 D:\project3\JNIAndroid\src>set classpath=D:\project3\JNIAndroid\src 1.2 设置classpath classpath    .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\tools.jar;E:\developLib\android\platforms\android-8\android.jar 2.基

JNI由浅入深_8_JNI缓存字段和方法ID

获取字段ID和方法ID时,需要用字段.方法的名字和描述符进行一个检索.检索过程相对比较费时,因此本节讨论用缓存技术来减少这个过程带来的消耗.缓存字段ID和方法ID的方法主要有两种.两种区别主要在于缓存发生的时刻,是在字段ID和方法ID被使用的时候,还是定义字段和方法的类静态初始化的时候. 1.使用时缓存 字段ID和方法ID可以在字段的值被访问或者方法被回调的时候缓存起来.下面的代码中把字段ID存储在静态变量当中,这样当本地方法被重复调用时,不必重新搜索字段ID. JNIEXPORT void J

JNI由浅入深_2_C语言基础

*含义 1.乘法 3*5 2.定义指针变量 int * p://定义了一个名字叫p的变量,能够存放int数据类型的地址 3.指针运算符, //如果p是一个已经定义好的指针变量则*p表示以p的内容为地址的变量 打印数据类型 %d - int %ld – long int %c - char %f - float %lf – double %x – 十六进制输出 int或者long int或者short int %o - 八进制输出 %s – 字符串 3.指针 指针就是地址. 热身小程序 介绍指针

JNI中java类型的简写

  在JNI中,当我们使用GetFieldID/GetStaticFieldID或GetMethodID/GetStaticMethodID及定义JNINativeMethod等时,我们需要表示成员变量的类型,或函数传入参数或返回的类型.JNI把Field的类型,或函数传入参数或返回值的类型进行简写以char*的形式进行表示.      对于成员变量,直接用java类型的简写表示成员变量的类型就可以      比如:"I"表示该成员变量是Int类型                 &q

Android JNI入门第二篇——Java参数类型与本地参数类型对照

前面一篇通过简单的例子介绍了android中JNI的使用.这一篇从基础上了解一些Java参数类型与本地参数类型区别. 1)        java中的返回值void和JNI中的void是完全对应的哦!(仅仅一个而已). 2)        java中的基本数据类型(byte ,short ,int,long,float,double ,boolean,char-8种)在JNI中对应的数据类型只要在前面加上j就对应了(jbyte ,jshort ,jint,jlong,jfloat,jdouble