《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”;失败时返回负数。


时间: 2024-10-27 14:14:03

《Java 本地接口规范》- JNI 函数(三)的相关文章

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

JNI 函数 本章为 JNI 函数提供参考信息.其中列出了全部 JNI 函数,同时也给出了 JNI 函数表的准确布局. 注意:"必须"一词用于约束 JNI 编程人员.例如,当说明某个 JNI 函数必须接收非空对象时,就应确保不要向该 JNI 函数传递 NULL.这时,JNI 实现将无需在该 JNI 函数中执行 NULL 指针检查. 本章的部分资料改编自 Netscape 的 JRI 文档. 该参考资料按用法对函数进行组织.参考部分按下列函数区域进行组织: 版本信息 类操作 异常 全局及

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

对象操作   AllocObject jobjectAllocObject(JNIEnv *env, jclass clazz); 分配新 Java 对象而不调用该对象的任何构造函数.返回该对象的引用. clazz 参数务必不要引用数组类. 参数: env:JNI 接口指针. clazz:Java 类对象. 返回值: 返回 Java 对象.如果无法构造该对象,则返回NULL. 抛出: InstantiationException:如果该类为一个接口或抽象类. OutOfMemoryError:如

《Java 本地接口规范》-JNI 的类型和数据结构

JNI 的类型和数据结构 本章讨论 JNI 如何将 Java 类型映射到本地 C 类型. 基本类型 表 3-1 描述Java 基本类型及其与计算机相关的本地等效类型. 表 3-1 基本类型和本地等效类型 Java 类型 本地类型 说明 boolean jboolean 无符号,8 位 byte jbyte 无符号,8 位 char jchar 无符号,16 位 short jshort 有符号,16 位 int jint 有符号,32 位 long jlong 有符号,64 位 float jf

《Java 本地接口规范》- 调用 API

调用 API 调用 API 允许软件厂商将 Java 虚拟机加载到任意的本地程序中.厂商可以交付支持 Java 的应用程序,而不必链接 Java 虚拟机源代码. 本章首先概述了调用 API.然后是所有调用 API 函数的引用页. 若要增强 Java 虚拟机的嵌入性,可以用几种方式来扩展 JDK 1.1.2 中的调用 API. 概述 以下代码示例说明了如何使用调用 API 中的函数.在本例中,C++ 代码创建 Java 虚拟机并且调用名为 Main.test 的静态方法.为清楚起见,我们略去了错误

JAVA JNI函数的注册过程详细介绍_java

JAVA JNI函数的注册过程详细介绍 我们在java中调用Native code的时候,一般是通过JNI来实现的,我们只需要在java类中加载本地.so库文件,并声明native方法,然后在需要调用的地方调用即可,至于java中native方法的具体实现,全部交给了Native层.我们要在java中正确地调用到本地代码中对应函数的前提是什么呢?答案就是通过一定的机制建立java中native方法和本地代码中函数的一一对应关系,那么这种机制是什么呢?就是JNI函数的注册机制. JNI函数的注册有

《Android的设计与实现:卷I》——第2章2.4 在Java中调用JNI实现方法

2.4 在Java中调用JNI实现方法 本节介绍如何在Java中调用JNI实现方法.JNI数据类型转换.JNI方法命名规则,以及JNI方法签名规则. 2.4.1 Java数据类型与JNI数据类型转换 Java中调用Native方法传递的参数是Java类型的,这些参数需要经过Dalvik虚拟机转化为JNI类型才能被JNI层识别.下面分基本类型和引用类型介绍这种转化关系. 1.基本类型转化关系 表2-1列出了基本类型的转化关系. 2.引用类型转化关系 JNI的引用类型定义了九种数组类型,以及jobj

JAVA本地接口(JNI)

JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++).从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了.使用java与本地已编译的代码交互,通常会丧失平台可移植性.但是,有些情况下这样做是可以接受的,甚至是必须的.例如,使用一些旧的库,与硬件.操作

用java写一个main函数,打印出1-6这这六个数字的所有不同的排列

1.2.2.3.4.5这六个数字,用java写一个main函数,打印出所有不同的排列, 如:512234.412345等.要求:"4"不能在第三位,"3"与"5"不能相连. package com.test; import java.util.ArrayList; import java.util.List; /** * 1.2.2.3.4.5这六个数字,用java写一个main函数,打印出所有不同的排列, 如:512234.412345等.要求

访问JNI函数:JNIEnv自变量

利用JNI函数,程序员可从一个固有方法的内部与JVM打交道.正如大家在前面的例子中看到的那样,每个JNI固有方法都会接收一个特殊的自变量作为自己的第一个参数:JNIEnv自变量--它是指向类型为JNIEnv_的一个特殊JNI数据结构的指针.JNI数据结构的一个元素是指向由JVM生成的一个数组的指针:该数组的每个元素都是指向一个JNI函数的指针.可从固有方法的内部发出对JNI函数的调用,做法是撤消对这些指针的引用(具体的操作实际很简单).每种JVM都以自己的方式实现了JNI函数,但它们的地址肯定位