NDK开发 从入门到放弃(四:JNI函数、C与C++调用函数的区别)

来源:互联网 发布:在线制作手机淘宝店招 编辑:程序博客网 时间:2024/06/06 09:55

前言

在之前的文章中我们看到过如下C++代码:

jclass clazz = env->FindClass("***/***/JNIDynamicUtils");

FindClass就属于jni函数。此文就来稍微讲解下一些常用的jni函数。

C与C++调用函数的区别

如上述代码,则是C++文件内的代码。标准的C实现上述代码的方式是:

jclass clazz = (*env)->FindClass(env, "***/***/JNIDynamicUtils");

看到不同的表示方式便能知道写的是C还是C++了。相比较的话,C++代码还是简洁一些。

JNI函数

以下为部分入门级函数,后续会不断补充。

1. FindClass

jclass FindClass(JNIEnv *env, const char *name);

该函数用于加载本地定义的类。

参数:
env:JNI接口指针。下面将不再介绍 ,在C++代码中,参数不传该值。
name:类全名(即包名后跟类名,之间由“/”分隔)。如果该名称以“[”(数组签名字符)打头,则返回一个数组类。

返回值:
返回类对象全名。如果找不到该类,则返回NULL。

抛出:
ClassFormatError:如果类数据指定的类无效。
ClassCircularityError:如果类或接口是自身的超类或超接口。
NoClassDefFoundError:如果找不到所请求的类或接口的定义。
OutOfMemoryError:如果系统内存不足。

2. GetMethodID

jmethodID GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig);

返回类或接口实例(非静态)方法的方法ID。方法可在某个clazz的超类中定义,也可从clazz继承。该方法由其名称和签名决定。GetMethodID()可使未初始化的类初始化。要获得构造函数的方法ID,应将<init>作为方法名,同时将()V作为返回类型。

参数:
clazz:Java类对象。
name:0终结的UTF-8字符串中的方法名。
sig:0终结的UTF-8字符串中的方法签名。

返回值:
方法ID,如果找不到指定的方法,则为NULL。

抛出:
NoSuchMethodError:如果找不到指定方法。
ExceptionInInitializerError:如果由于异常而导致类初始化程序失败。
OutOfMemoryError:如果系统内存不足。

3. NewObject

jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...);

构造新Java对象。方法ID必须通过调用GetMethodID()获得,为应调用的构造函数方法。clazz参数务必不要引用数组类。

参数:
clazz:Java类对象。
methodID:构造函数的方法ID。
其它参数:传给构造函数的参数。

返回值:
返回Java对象,如果无法构造该对象,则返回NULL。

抛出:
InstantiationException:如果该类为接口或抽象类。
OutOfMemoryError:如果系统内存不足。
其他:构造函数抛出的任何异常。

4. NewStringUTF

jstring NewStringUTF(JNIEnv *env, const char *bytes);

利用UTF-8字符数组构造新java.lang.String对象。

参数:
bytes:指向UTF-8字符串的指针。

返回值:
Java字符串对象。如果无法构造该字符串,则为NULL。

抛出:
OutOfMemoryError:如果系统内存不足。

5. GetStringUTFLength

jsize GetStringUTFLength(JNIEnv *env, jstring string);

以字节为单位返回字符串的UTF-8长度。

参数:
string:Java字符串对象。

返回值:
返回字符串的UTF-8长度。若参数为null,则会异常。

6. Throw

jint Throw(JNIEnv *env, jthrowable obj);

抛出java.lang.Throwable异常对象。

参数:
obj:java.lang.Throwable对象。

返回值:
成功时返回0,失败时返回负数。

抛出:
java.lang.Throwable对象obj。

tip:
与java不同,抛出异常后,后续代码还会继续执行,直至return。

7. ThrowNew

jint ThrowNew(JNIEnv *env, jclass clazz, const char *message);

利用指定类的消息(由message指定)构造异常对象并抛出该异常。

参数:
clazz:java.lang.Throwable的子类。
message:用于构造java.lang.Throwable对象的消息。

返回值:
成功时返回0,失败时返回负数。

抛出:
新构造的java.lang.Throwable对象。

8. GetArrayElements

 NativeType *Get<PrimitiveType>ArrayElements (JNIEnv *env, ArrayType array, jboolean*isCopy); 

一组返回基本类型数组体的函数。结果在调用相应的ReleaseArrayElements()函数前将一直有效。由于返回的数组可能是Java数组的副本,因此对返回数组的更改不必在基本类型数组中反映出来,直到调用了 ReleaseArrayElements()。如果isCopy不是NULL,*isCopy在复制完成后即被设为JNI_TRUE。如果未复制,则设为JNI_FALSE。

GetArrayElements例程 数组类型 本地类型 GetBooleanArrayElements() jbooleanArray jboolean GetByteArrayElements() jbyteArray jbyte GetCharArrayElements() jcharArray jchar GetShortArrayElements() jshortArray jshort GetIntArrayElements() jintArray jint GetLongArrayElements() jlongArray jlong GetFloatArrayElements() jfloatArray jfloat GetDoubleArrayElements() jdoubleArray jdouble

参数:
array:Java字符串对象。
isCopy:指向布尔值的指针。

返回值:
返回指向数组元素的指针,如果操作失败,则为NULL。

9. ReleaseArrayElements

void Release<PrimitiveType>ArrayElements(JNIEnv *env, ArrayType array, NativeType *elems, jint mode);

通知虚拟机平台相关代码无需再访问elems的一组函数。elems参数是一个通过使用对应的GetArrayElements()函数由array导出的指针。必要时,该函数将把对elems的修改复制回基本类型数组。mode参数将提供有关如何释放数组缓冲区的信息。 如果elems不是array中数组元素的副本,mode将无效。否则,mode将具有下表所述的功能:

基本类型数组释放模 动作 0 复制回内容并释放elems缓冲区 JNI_COMMIT 复制回内容但不释放elems缓冲区 JNI_ABORT 释放缓冲区但不复制回变化

多数情况下,编程人员将把“0”传给mode参数以确保固定的数组和复制的数组保持一致。其它选项可以使编程人员进一步控制内存 管理,但使用时务必慎重。

参数:
array:Java数组对象。
elems:指向数组元素的指针。
mode:释放模式。

10. NewArray

ArrayType New<PrimitiveType>Array(JNIEnv *env, jsize length);

用于构造新基本类型数组对象的一系列操作。下表说明了特定的基本类型数组构造函数。用户应把NewArray替换为 某个实际的基本类型数组构造函数例程名(见下表),然后将ArrayType替换为该例程相应的数组类型。

NewArray例程 数组类型 NewBooleanArray() jbooleanArray NewByteArray() jbyteArray NewCharArray() jcharArray NewShortArray() jshortArray NewIntArray() jintArray NewLongArray() jlongArray NewFloatArray() jfloatArray NewDoubleArray() jdoubleArray

参数:
length:数组长度。

返回值:
Java数组。如果无法构造该数组,则为NULL。

11. SetArrayRegion

void Set<PrimitiveType>ArrayRegion(JNIEnv *env, ArrayType array, jsize start, jsize len, NativeType *buf);

将基本类型数组的某一区域从缓冲区中复制回来的一组函数。下表说明了特定的基本类型数组元素访问器。应进行如下替换:

SetArrayRegion例程 数组类型 本地类型 SetBooleanArrayRegion() jbooleanArray jboolean SetByteArrayRegion() jbyteArray jbyte SetCharArrayRegion() jcharArray jchar SetShortArrayRegion() jshortArray jshort SetIntArrayRegion() jintArray jint SetLongArrayRegion() jlongArray jlong SetFloatArrayRegion() jfloatArray jfloat SetDoubleArrayRegion() jdoubleArray jdouble

参数:
array: Java数组。
start:起始下标。
len:要复制的元素数。
buf:源缓冲区。

抛出:
ArrayIndexOutOfBoundsException:如果区域中的某个下标无效。

1 0
原创粉丝点击