《Java 本地接口规范》- JNI 函数(三)

简介:

字符串操作

 

NewString

jstringNewString(JNIEnv *env, const jchar *unicodeChars,
jsize len);

利用 Unicode 字符数组构造新的 java.lang.String 对象。

参数:

env:JNI 接口指针。

unicodeChars:指向 Unicode 字符串的指针。

len:Unicode 字符串的长度。

返回值:

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

抛出:

OutOfMemoryError:如果系统内存不足。

 

GetStringLength

jsizeGetStringLength(JNIEnv *env, jstring string);

返回 Java 字符串的长度(Unicode 字符数)。

参数:

env:JNI 接口指针。

string:Java 字符串对象。

返回值:

Java 字符串的长度。

 

GetStringChars

constjchar * GetStringChars(JNIEnv *env, jstring string,
jboolean *isCopy);

返回指向字符串的 Unicode 字符数组的指针。该指针在调用 ReleaseStringchars() 前一直有效。

如果 isCopy 非空,则在复制完成后将 *isCopy 设为 JNI_TRUE。如果没有复制,则设为JNI_FALSE

参数:

env:JNI 接口指针。

string:Java 字符串对象。

isCopy:指向布尔值的指针。

返回值:

指向 Unicode 字符串的指针,如果操作失败,则返回NULL

 

ReleaseStringChars

voidReleaseStringChars(JNIEnv *env, jstring string,
const jchar *chars);

通知虚拟机平台相关代码无需再访问 chars。参数 chars 是一个指针,可通过 GetStringChars()string 获得。

参数:

env:JNI 接口指针。

string:Java 字符串对象。

chars:指向 Unicode 字符串的指针。

 

NewStringUTF

jstringNewStringUTF(JNIEnv *env, const char *bytes);

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

参数:

env:JNI 接口指针。如果无法构造该字符串,则为 NULL

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

返回值:

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

抛出:

OutOfMemoryError:如果系统内存不足。

 

GetStringUTFLength

jsizeGetStringUTFLength(JNIEnv *env, jstring string);

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

参数:

env:JNI 接口指针。

string:Java 字符串对象。

返回值:

返回字符串的 UTF-8 长度。

 

GetStringUTFChars

constchar* GetStringUTFChars(JNIEnv *env, jstring string,
jboolean *isCopy);

返回指向字符串的 UTF-8 字符数组的指针。该数组在被ReleaseStringUTFChars() 释放前将一直有效。

如果 isCopy 不是 NULL*isCopy 在复制完成后即被设为 JNI_TRUE。如果未复制,则设为 JNI_FALSE

参数:

env:JNI 接口指针。

string:Java 字符串对象。

isCopy:指向布尔值的指针。

返回值:

指向 UTF-8 字符串的指针。如果操作失败,则为 NULL

 

ReleaseStringUTFChars

voidReleaseStringUTFChars(JNIEnv *env, jstring string,
const char *utf);

通知虚拟机平台相关代码无需再访问 utfutf 参数是一个指针,可利用 GetStringUTFChars()string 获得。

参数:

env:JNI 接口指针。

string:Java 字符串对象。

utf:指向 UTF-8 字符串的指针。


数组操作

 

GetArrayLength

jsizeGetArrayLength(JNIEnv *env, jarray array);

返回数组中的元素数。

参数:

env:JNI 接口指针。

array:Java 数组对象。

返回值:

数组的长度。

 

NewObjectArray

jarrayNewObjectArray(JNIEnv *env, jsize length,
jclass elementClass, jobject initialElement);

构造新的数组,它将保存类 elementClass 中的对象。所有元素初始值均设为 initialElement

参数:

env:JNI 接口指针。

length:数组大小。

elementClass:数组元素类。

initialElement:初始值。

返回值:

Java 数组对象。如果无法构造数组,则为 NULL

抛出:

OutOfMemoryError:如果系统内存不足。

 

GetObjectArrayElement

jobjectGetObjectArrayElement(JNIEnv *env,
jobjectArray array, jsize index);

返回 Object 数组的元素。

参数:

env:JNI 接口指针。

array:Java 数组。

index:数组下标。

返回值:

Java 对象。

抛出:

ArrayIndexOutOfBoundsException:如果 index 不是数组中的有效下标。

 

SetObjectArrayElement

voidSetObjectArrayElement(JNIEnv *env, jobjectArray array,
jsize index, jobject value);

设置 Object 数组的元素。

参数:

env:JNI 接口指针。

array:Java 数组。

index:数组下标。

value:新值。

抛出:

ArrayIndexOutOfBoundsException:如果 index 不是数组中的有效下标。

ArrayStoreException:如果 value 的类不是数组元素类的子类。

 

New<PrimitiveType>Array 例程

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

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

表 4-8 New<PrimitiveType>Array 数组构造函数系列

New<PrimitiveType>Array 例程

数组类型

NewBooleanArray()

jbooleanArray

NewByteArray()

jbyteArray

NewCharArray()

jcharArray

NewShortArray()

jshortArray

NewIntArray()

jintArray

NewLongArray()

jlongArray

NewFloatArray()

jfloatArray

NewDoubleArray()

jdoubleArray

参数:

env:JNI 接口指针。

length:数组长度。

返回值:

Java 数组。如果无法构造该数组,则为 NULL

 

Get<PrimitiveType>ArrayElements 例程

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

一组返回基本类型数组体的函数。结果在调用相应的 Release<PrimitiveType>ArrayElements()函数前将一直有效。由于返回的数组可能是 Java 数组的副本,因此对返回数组的更改不必在基本类型数组中反映出来,直到调用了Release<PrimitiveType>ArrayElements()

如果 isCopy 不是 NULL*isCopy 在复制完成后即被设为 JNI_TRUE。如果未复制,则设为 JNI_FALSE

下表说明了特定的基本类型数组元素访问器。应进行下列替换;

  • 将 Get<PrimitiveType>ArrayElements 替换为表中某个实际的基本类型元素访问器例程名。
  • ArrayType 替换为对应的数组类型。
  • 将 NativeType 替换为该例程对应的本地类型。

不管布尔数组在 Java 虚拟机中如何表示,GetBooleanArrayElements() 将始终返回一个 jbooleans 类型的指针,其中每一字节代表一个元素(开包表示)。内存中将确保所有其它类型的数组为连续的。

表4-9 Get<PrimitiveType>ArrayElements 访问器例程系列

Get<PrimitiveType>ArrayElements 例程

数组类型

本地类型

GetBooleanArrayElements()

jbooleanArray

jboolean

GetByteArrayElements()

jbyteArray

jbyte

GetCharArrayElements()

jcharArray

jchar

GetShortArrayElements()

jshortArray

jshort

GetIntArrayElements()

jintArray

jint

GetLongArrayElements()

jlongArray

jlong

GetFloatArrayElements()

jfloatArray

jfloat

GetDoubleArrayElements()

jdoubleArray

jdouble

参数:

env:JNI 接口指针。

array:Java 字符串对象。

isCopy:指向布尔值的指针。

返回值:

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

 

Release<PrimitiveType>ArrayElements 例程

voidRelease<PrimitiveType>ArrayElements(JNIEnv *env,
ArrayType array, NativeType *elems, jintmode);

通知虚拟机平台相关代码无需再访问 elems 的一组函数。elems 参数是一个通过使用对应的Get<PrimitiveType>ArrayElements() 函数由 array 导出的指针。必要时,该函数将把对 elems 的修改复制回基本类型数组。

mode参数将提供有关如何释放数组缓冲区的信息。如果elems 不是 array 中数组元素的副本,mode将无效。否则,mode 将具有下表所述的功能:

表 4-10 基本类型数组释放模式

模式

动作

0

复制回内容并释放 elems 缓冲区

JNI_COMMIT

复制回内容但不释放 elems 缓冲区

JNI_ABORT

释放缓冲区但不复制回变化

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

下表说明了构成基本类型数组撤消程序系列的特定例程。应进行如下替换;

  • 将 Release<PrimitiveType>ArrayElements 替换为表 4-11 中的某个实际基本类型数组撤消程序例程名。 
  • ArrayType 替换为对应的数组类型。
  • 将 NativeType 替换为该例程对应的本地类型。

表 4-11 Release<PrimitiveType>ArrayElements 数组例程系列

Release<PrimitiveType>ArrayElements 例程

数组类型

本地类型

ReleaseBooleanArrayElements()

jbooleanArray

jboolean

ReleaseByteArrayElements()

jbyteArray

jbyte

ReleaseCharArrayElements()

jcharArray

jchar

ReleaseShortArrayElements()

jshortArray

jshort

ReleaseIntArrayElements()

jintArray

jint

ReleaseLongArrayElements()

jlongArray

jlong

ReleaseFloatArrayElements()

jfloatArray

jfloat

ReleaseDoubleArrayElements()

jdoubleArray

jdouble

参数:

env:JNI 接口指针。

array:Java 数组对象。

elems:指向数组元素的指针。

mode:释放模式。

 

Get<PrimitiveType>ArrayRegion 例程

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

将基本类型数组某一区域复制到缓冲区中的一组函数。

下表说明了特定的基本类型数组元素访问器。应进行如下替换:

  • 将 Get<PrimitiveType>ArrayRegion 替换为表 4-12 中的某个实际基本类型元素访问器例程名。
  • 将 ArrayType 替换为对应的数组类型。
  • 将 NativeType 替换为该例程对应的本地类型。

表 4-12 Get<PrimitiveType>ArrayRegion 数组访问器例程系列

Get<PrimitiveType>ArrayRegion 例程

数组类型

本地类型

GetBooleanArrayRegion()

jbooleanArray

jboolean

GetByteArrayRegion()

jbyteArray

jbyte

GetCharArrayRegion()

jcharArray

jchar

GetShortArrayRegion()

jshortArray

jhort

GetIntArrayRegion()

jintArray

jint

GetLongArrayRegion()

jlongArray

jlong

GetFloatArrayRegion()

jfloatArray

jloat

GetDoubleArrayRegion()

jdoubleArray

jdouble

参数:

env:JNI 接口指针。

array:Java 指针。

start:起始下标。

len:要复制的元素数。

buf:目的缓冲区。

抛出:

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

 

Set<PrimitiveType>ArrayRegion 例程

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

将基本类型数组的某一区域从缓冲区中复制回来的一组函数。

下表说明了特定的基本类型数组元素访问器。应进行如下替换:

  • 将 Set<PrimitiveType>ArrayRegion 替换为表中的实际基本类型元素访问器例程名。
  • ArrayType 替换为对应的数组类型。
  • 将 NativeType 替换为该例程对应的本地类型。

表 4-13 Set<PrimitiveType>ArrayRegion 数组访问器例程系列

Set<PrimitiveType>ArrayRegion 例程

数组类型

本地类型

SetBooleanArrayRegion()

jbooleanArray

jboolean

SetByteArrayRegion()

jbyteArray

jbyte

SetCharArrayRegion()

jcharArray

jchar

SetShortArrayRegion()

jshortArray

jshort

SetIntArrayRegion()

jintArray

jint

SetLongArrayRegion()

jlongArray

jlong

SetFloatArrayRegion()

jfloatArray

jfloat

SetDoubleArrayRegion()

jdoubleArray

jdouble

参数:

env:JNI 接口指针。

array:  Java 数组。

start:起始下标。

len:要复制的元素数。

buf:源缓冲区。

抛出:

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


注册本地方法

 

RegisterNatives

jintRegisterNatives(JNIEnv *env, jclass clazz,
const JNINativeMethod *methods, jint nMethods);

clazz 参数指定的类注册本地方法。methods 参数将指定 JNINativeMethod 结构的数组,其中包含本地方法的名称、签名和函数指针。nMethods 参数将指定数组中的本地方法数。JNINativeMethod 结构定义如下所示:

    typedef struct {
        char *name;
        char *signature;
        void *fnPtr;
    } JNINativeMethod;

函数指针通常必须有下列签名:

    ReturnType (*fnPtr)(JNIEnv *env, jobject objectOrClass, ...);

参数:

env:JNI 接口指针。

clazz:Java 类对象。

methods:类中的本地方法。

nMethods:类中的本地方法数。

返回值:

成功时返回 "0";失败时返回负数。

抛出:

NoSuchMethodError:如果找不到指定的方法或方法不是本地方法。

 

UnregisterNatives

jintUnregisterNatives(JNIEnv *env, jclass clazz);

取消注册类的本地方法。类将返回到链接或注册了本地方法函数前的状态。

该函数不应在常规平台相关代码中使用。相反,它可以为某些程序提供一种重新加载和重新链接本地库的途径。

参数:

env:JNI 接口指针。

clazz:Java 类对象。

返回值:

成功时返回“0”;失败时返回负数。


监视程序操作

 

MonitorEnter

jintMonitorEnter(JNIEnv *env, jobject obj);

进入与 obj 所引用的基本 Java 对象相关联的监视程序。

每个 Java 对象都有一个相关联的监视程序。如果当前线程已经拥有与obj 相关联的监视程序,它将使指示该线程进入监视程序次数的监视程序计数器增 1。如果与 obj 相关联的监视程序并非由某个线程所拥有,则当前线程将变为该监视程序的所有者,同时将该监视程序的计数器设置为 1。如果另一个线程已拥有与 obj 关联的监视程序,则在监视程序被释放前当前线程将处于等待状态。监视程序被释放后,当前线程将尝试重新获得所有权。

参数:

env:JNI 接口指针。

obj:常规 Java 对象或类对象。

返回值:

成功时返回“0”;失败时返回负数。

 

MonitorExit

jintMonitorExit(JNIEnv *env, jobject obj);

当前线程必须是与 obj 所引用的基本 Java 对象相关联的监视程序的所有者。线程将使指示进入监视程序次数的计数器减 1。如果计数器的值变为 0,当前线程释放监视程序。

参数:

env:JNI 接口指针。

obj:常规 Java 对象或类对象。

返回值:

成功时返回“0”;失败时返回负数。


Java 虚拟机接口

 

GetJavaVM

jintGetJavaVM(JNIEnv *env, JavaVM **vm);

返回与当前线程相关联的 Java 虚拟机接口(用于调用 API 中)。结果将放在第二个参数 vm 所指向的位置。

参数:

env:JNI 接口指针。

vm:指向放置结果的位置的指针。

返回值:

成功时返回“0”;失败时返回负数。


相关文章
|
1月前
|
JavaScript 前端开发 Java
Java Script中的函数原型是什么
Java Script中的函数原型是什么
11 0
|
5月前
|
JavaScript 前端开发 Java
javascript实现像java、c#之类的sleep暂停的函数功能
javascript实现像java、c#之类的sleep暂停的函数功能
41 0
|
5月前
|
Java
java实现Beta函数
java实现Beta函数
|
6月前
|
缓存 算法 Java
在阿里云上部署和运行Java函数时
在阿里云上部署和运行Java函数时
94 2
|
1月前
|
Java 数据库连接 API
Java 学习路线:基础知识、数据类型、条件语句、函数、循环、异常处理、数据结构、面向对象编程、包、文件和 API
Java 是一种广泛使用的、面向对象的编程语言,始于1995年,以其跨平台性、安全性和可靠性著称,应用于从移动设备到数据中心的各种场景。基础概念包括变量(如局部、实例和静态变量)、数据类型(原始和非原始)、条件语句(if、else、switch等)、函数、循环、异常处理、数据结构(如数组、链表)和面向对象编程(类、接口、继承等)。深入学习还包括包、内存管理、集合框架、序列化、网络套接字、泛型、流、JVM、垃圾回收和线程。构建工具如Gradle、Maven和Ant简化了开发流程,Web框架如Spring和Spring Boot支持Web应用开发。ORM工具如JPA、Hibernate处理对象与数
94 3
|
3月前
|
Java
java的OutputStream.writeUTF()函数
java的OutputStream.writeUTF()函数
34 4
|
4月前
|
存储 安全 Java
java标识符命名规范--代码格式规范--注释规范--最佳实践和禁忌--代码示例
java标识符命名规范--代码格式规范--注释规范--最佳实践和禁忌--代码示例
135 0
|
4月前
|
算法 Java
给定一个字符串数组,如何找到其中最长的回文子串? 要求:编写一个Java函数,输入一个字符串数组,输出其中最长的回文子串。要求时间复杂度为O(n^2)。可以考虑使用动态规划或中心扩展的方法来优化算法。
给定一个字符串数组,如何找到其中最长的回文子串? 要求:编写一个Java函数,输入一个字符串数组,输出其中最长的回文子串。要求时间复杂度为O(n^2)。可以考虑使用动态规划或中心扩展的方法来优化算法。
41 1
|
5月前
|
Java
“Java 8新特性:Lambda表达式与函数引用的详细之道“
“Java 8新特性:Lambda表达式与函数引用的详细之道“
|
5月前
|
JavaScript Java
java函数防抖
java函数防抖
30 0