Java本机接口规范内容 第4章:JNI函数

本章作为JNI函数的参考部分。 它提供了所有JNI功能的完整列表。 它还提供了JNI函数表的确切布局。

请注意使用术语“必须”来描述对JNI程序员的限制。 例如,当您看到某个JNI函数必须接收非NULL对象时,您有责任确保不将NULL传递给该JNI函数。 因此,JNI实现不需要在该JNI函数中执行NULL指针检查。

本章的一部分改编自Netscape的JRI文档。

参考材料按其用法分组。 参考部分由以下功能区域组成:

目录

接口功能表

版本信息

GetVersion

常量

班级操作

的defineClass

findClass的

getSuperclass之

IsAssignableFrom

例外

ThrowNew

ExceptionOccurred

ExceptionDescribe

ExceptionClear

致命错误

ExceptionCheck

全球和本地参考

全球参考

NewGlobalRef

DeleteGlobalRef

本地参考

DeleteLocalRef

EnsureLocalCapacity

PushLocalFrame

PopLocalFrame

NewLocalRef

弱全球参考

NewWeakGlobalRef

DeleteWeakGlobalRef

对象操作

AllocObject

NewObject,NewObjectA,NewObjectV

GetObjectClass

GetObjectRefType

IsInstanceOf

IsSameObject

访问对象的字段

GetFieldID

获取 Field Routines

设置 Field Routines

调用实例方法

的GetMethodID

调用 Method Routines,Call MethodA Routines,Call MethodV Routines

CallNonvirtual Method Routines,CallNonvirtual MethodA Routines,CallNonvirtual MethodV Routines

访问静态字段

GetStaticFieldID

GetStatic Field Routines

SetStatic Field Routines

调用静态方法

GetStaticMethodID

CallStatic Method Routines,CallStatic MethodA Routines,CallStatic MethodV Routines

字符串操作

NewString

GetStringLength

GetStringChars

ReleaseStringChars

NewStringUTF

GetStringUTFLength

GetStringUTFChars

ReleaseStringUTFChars

GetStringRegion

GetStringUTFRegion

GetStringCritical,ReleaseStringCritical

阵列操作

GetArrayLength

NewObjectArray

GetObjectArrayElement

SetObjectArrayElement

新的数组例程

获取 ArrayElements例程

发布 ArrayElements例程

获取 ArrayRegion例程

设置 ArrayRegion例程

GetPrimitiveArrayCritical,ReleasePrimitiveArrayCritical

注册本机方法

RegisterNatives

UnregisterNatives

监控操作

MonitorEnter

MonitorExit

NIO支持

NewDirectByteBuffer

GetDirectBufferAddress

GetDirectBufferCapacity

反思支持

FromReflectedMethod

FromReflectedField

ToReflectedMethod

ToReflectedField

Java VM接口

GetJavaVM


接口功能表

可以通过JNIEnv参数以固定偏移量访问每个函数。 JNIEnv类型是指向存储所有JNI函数指针的结构的指针。 它的定义如下:

typedef const struct JNINativeInterface *JNIEnv;

VM初始化函数表,如以下代码示例所示。 请注意,前三个条目保留用于将来与COM的兼容性。 此外,我们在函数表的开头附近保留了一些额外的NULL条目,因此,例如,可以在FindClass之后而不是在表的末尾添加与类相关的未来JNI操作。

请注意,函数表可以在所有JNI接口指针之间共享。

const struct JNINativeInterface ... = {

    NULL,
    NULL,
    NULL,
    NULL,
    GetVersion,

    DefineClass,
    FindClass,

    FromReflectedMethod,
    FromReflectedField,
    ToReflectedMethod,

    GetSuperclass,
    IsAssignableFrom,

    ToReflectedField,

    Throw,
    ThrowNew,
    ExceptionOccurred,
    ExceptionDescribe,
    ExceptionClear,
    FatalError,

    PushLocalFrame,
    PopLocalFrame,

    NewGlobalRef,
    DeleteGlobalRef,
    DeleteLocalRef,
    IsSameObject,
    NewLocalRef,
    EnsureLocalCapacity,

    AllocObject,
    NewObject,
    NewObjectV,
    NewObjectA,

    GetObjectClass,
    IsInstanceOf,

    GetMethodID,

    CallObjectMethod,
    CallObjectMethodV,
    CallObjectMethodA,
    CallBooleanMethod,
    CallBooleanMethodV,
    CallBooleanMethodA,
    CallByteMethod,
    CallByteMethodV,
    CallByteMethodA,
    CallCharMethod,
    CallCharMethodV,
    CallCharMethodA,
    CallShortMethod,
    CallShortMethodV,
    CallShortMethodA,
    CallIntMethod,
    CallIntMethodV,
    CallIntMethodA,
    CallLongMethod,
    CallLongMethodV,
    CallLongMethodA,
    CallFloatMethod,
    CallFloatMethodV,
    CallFloatMethodA,
    CallDoubleMethod,
    CallDoubleMethodV,
    CallDoubleMethodA,
    CallVoidMethod,
    CallVoidMethodV,
    CallVoidMethodA,

    CallNonvirtualObjectMethod,
    CallNonvirtualObjectMethodV,
    CallNonvirtualObjectMethodA,
    CallNonvirtualBooleanMethod,
    CallNonvirtualBooleanMethodV,
    CallNonvirtualBooleanMethodA,
    CallNonvirtualByteMethod,
    CallNonvirtualByteMethodV,
    CallNonvirtualByteMethodA,
    CallNonvirtualCharMethod,
    CallNonvirtualCharMethodV,
    CallNonvirtualCharMethodA,
    CallNonvirtualShortMethod,
    CallNonvirtualShortMethodV,
    CallNonvirtualShortMethodA,
    CallNonvirtualIntMethod,
    CallNonvirtualIntMethodV,
    CallNonvirtualIntMethodA,
    CallNonvirtualLongMethod,
    CallNonvirtualLongMethodV,
    CallNonvirtualLongMethodA,
    CallNonvirtualFloatMethod,
    CallNonvirtualFloatMethodV,
    CallNonvirtualFloatMethodA,
    CallNonvirtualDoubleMethod,
    CallNonvirtualDoubleMethodV,
    CallNonvirtualDoubleMethodA,
    CallNonvirtualVoidMethod,
    CallNonvirtualVoidMethodV,
    CallNonvirtualVoidMethodA,

    GetFieldID,

    GetObjectField,
    GetBooleanField,
    GetByteField,
    GetCharField,
    GetShortField,
    GetIntField,
    GetLongField,
    GetFloatField,
    GetDoubleField,
    SetObjectField,
    SetBooleanField,
    SetByteField,
    SetCharField,
    SetShortField,
    SetIntField,
    SetLongField,
    SetFloatField,
    SetDoubleField,

    GetStaticMethodID,

    CallStaticObjectMethod,
    CallStaticObjectMethodV,
    CallStaticObjectMethodA,
    CallStaticBooleanMethod,
    CallStaticBooleanMethodV,
    CallStaticBooleanMethodA,
    CallStaticByteMethod,
    CallStaticByteMethodV,
    CallStaticByteMethodA,
    CallStaticCharMethod,
    CallStaticCharMethodV,
    CallStaticCharMethodA,
    CallStaticShortMethod,
    CallStaticShortMethodV,
    CallStaticShortMethodA,
    CallStaticIntMethod,
    CallStaticIntMethodV,
    CallStaticIntMethodA,
    CallStaticLongMethod,
    CallStaticLongMethodV,
    CallStaticLongMethodA,
    CallStaticFloatMethod,
    CallStaticFloatMethodV,
    CallStaticFloatMethodA,
    CallStaticDoubleMethod,
    CallStaticDoubleMethodV,
    CallStaticDoubleMethodA,
    CallStaticVoidMethod,
    CallStaticVoidMethodV,
    CallStaticVoidMethodA,

    GetStaticFieldID,

    GetStaticObjectField,
    GetStaticBooleanField,
    GetStaticByteField,
    GetStaticCharField,
    GetStaticShortField,
    GetStaticIntField,
    GetStaticLongField,
    GetStaticFloatField,
    GetStaticDoubleField,

    SetStaticObjectField,
    SetStaticBooleanField,
    SetStaticByteField,
    SetStaticCharField,
    SetStaticShortField,
    SetStaticIntField,
    SetStaticLongField,
    SetStaticFloatField,
    SetStaticDoubleField,

    NewString,

    GetStringLength,
    GetStringChars,
    ReleaseStringChars,

    NewStringUTF,
    GetStringUTFLength,
    GetStringUTFChars,
    ReleaseStringUTFChars,

    GetArrayLength,

    NewObjectArray,
    GetObjectArrayElement,
    SetObjectArrayElement,

    NewBooleanArray,
    NewByteArray,
    NewCharArray,
    NewShortArray,
    NewIntArray,
    NewLongArray,
    NewFloatArray,
    NewDoubleArray,

    GetBooleanArrayElements,
    GetByteArrayElements,
    GetCharArrayElements,
    GetShortArrayElements,
    GetIntArrayElements,
    GetLongArrayElements,
    GetFloatArrayElements,
    GetDoubleArrayElements,

    ReleaseBooleanArrayElements,
    ReleaseByteArrayElements,
    ReleaseCharArrayElements,
    ReleaseShortArrayElements,
    ReleaseIntArrayElements,
    ReleaseLongArrayElements,
    ReleaseFloatArrayElements,
    ReleaseDoubleArrayElements,

    GetBooleanArrayRegion,
    GetByteArrayRegion,
    GetCharArrayRegion,
    GetShortArrayRegion,
    GetIntArrayRegion,
    GetLongArrayRegion,
    GetFloatArrayRegion,
    GetDoubleArrayRegion,
    SetBooleanArrayRegion,
    SetByteArrayRegion,
    SetCharArrayRegion,
    SetShortArrayRegion,
    SetIntArrayRegion,
    SetLongArrayRegion,
    SetFloatArrayRegion,
    SetDoubleArrayRegion,

    RegisterNatives,
    UnregisterNatives,

    MonitorEnter,
    MonitorExit,

    GetJavaVM,

    GetStringRegion,
    GetStringUTFRegion,

    GetPrimitiveArrayCritical,
    ReleasePrimitiveArrayCritical,

    GetStringCritical,
    ReleaseStringCritical,

    NewWeakGlobalRef,
    DeleteWeakGlobalRef,

    ExceptionCheck,

    NewDirectByteBuffer,
    GetDirectBufferAddress,
    GetDirectBufferCapacity,

    GetObjectRefType
  };

版本信息

GetVersion

jint GetVersion(JNIEnv *env);

返回本机方法接口的版本。

连锁:

JNIEnv接口函数表中的索引4。

参数:

env :JNI接口指针。

返回值:

返回高16位的主版本号和低16位的次版本号。

在JDK / JRE 1.1中, GetVersion()返回0x00010001 。

在JDK / JRE 1.2中, GetVersion()返回0x00010002 。

在JDK / JRE 1.4中, GetVersion()返回0x00010004 。

在JDK / JRE 1.6中, GetVersion()返回0x00010006 。

常量

自JDKE / JRE 1.2起:

#define JNI_VERSION_1_1 0x00010001
#define JNI_VERSION_1_2 0x00010002

/* Error codes */
#define JNI_EDETACHED    (-2)              /* thread detached from the VM */
#define JNI_EVERSION     (-3)              /* JNI version error 

自JDKE / JRE 1.4起:

 #define JNI_VERSION_1_4 0x00010004

自JDKE / JRE 1.6起:

 #define JNI_VERSION_1_6 0x00010006

类操作

defineClass

jclass DefineClass(JNIEnv *env, const char *name, jobject loader, 
const jbyte *buf, jsize bufLen);

从原始类数据的缓冲区加载一个类。 在DefineClass调用返回后,VM不会引用包含原始类数据的缓冲区,如果需要,可以将其丢弃。

连锁:

JNIEnv接口函数表中的索引5。

参数:

env :JNI接口指针。

name :要定义的类或接口的名称。 该字符串以修改后的UTF-8编码。

loader :分配给已定义类的类加载器。

buf :包含.class文件数据的缓冲区。

bufLen :缓冲区长度。

返回值:

如果发生错误,则返回Java类对象或NULL 。

抛出:

ClassFormatError :如果类数据未指定有效类。

ClassCircularityError :如果类或接口是它自己的超类或超接口。

OutOfMemoryError :如果系统内存不足。

SecurityException :如果调用者尝试在“java”包树中定义一个类。

findClass

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

在JDK 1.1版中,此函数加载本地定义的类。 它搜索CLASSPATH环境变量指定的目录和zip文件,以查找具有指定名称的类。

从Java 2 SDK 1.2版开始,Java安全模型允许非系统类加载和调用本机方法。 FindClass定位与当前本机方法关联的类加载器; 也就是说,声明本机方法的类的类加载器。 如果本机方法属于系统类,则不涉及类加载器。 否则,将调用适当的类加载器来加载和链接命名类。

从Java 2 SDK 1.2版开始,当通过调用接口调用FindClass时,没有当前的本机方法或其关联的类加载器。 在这种情况下,使用ClassLoader.getSystemClassLoader的结果。 这是虚拟机为应用程序创建的类加载器,并且能够定位java.class.path属性中列出的类。

name参数是完全限定的类名或数组类型签名。 例如, java.lang.String类的完全限定类名是:

 "java/lang/String"

数组类java.lang.Object[]的数组类型签名是:

"[Ljava/lang/Object;"

连锁:

JNIEnv接口函数表中的索引6。

参数:

env :JNI接口指针。

name :完全限定的类名(即包名,由“ / ”分隔,后跟类名)。 如果名称以“ [ ”(数组签名字符)开头,则返回数组类。 该字符串以修改后的UTF-8编码。

返回值:

从完全限定名称返回类对象,如果找不到类,则返回NULL 。

抛出:

ClassFormatError :如果类数据未指定有效类。

ClassCircularityError :如果类或接口是它自己的超类或超接口。

NoClassDefFoundError :如果找不到所请求的类或接口的定义。

OutOfMemoryError :如果系统内存不足。

getSuperclass

jclass GetSuperclass(JNIEnv *env, jclass clazz);

如果clazz表示除Object类之外的任何类,则此函数返回表示clazz指定的类的超类的clazz 。

如果clazz指定类Object ,或者clazz表示接口,则此函数返回NULL 。

连锁:

JNIEnv接口函数表中的索引10。

参数:

env :JNI接口指针。

clazz :一个Java类对象。

返回值:

返回clazz表示的类的超类,或NULL 。

IsAssignableFrom

jboolean IsAssignableFrom(JNIEnv *env, jclass clazz1, 
jclass clazz2);

确定clazz1的对象是否可以安全地转换为clazz2 。

连锁:

JNIEnv接口函数表中的索引11。

参数:

env :JNI接口指针。

clazz1 :第一类参数。

clazz2 :第二类参数。

返回值:

如果满足以下任一条件,则返回JNI_TRUE :

  • 第一个和第二个类参数引用相同的Java类。
  • 第一个类是第二个类的子类。
  • 第一个类将第二个类作为其接口之一。

异常

抛异常

jint Throw(JNIEnv *env, jthrowable obj);

导致抛出java.lang.Throwable对象。

连锁:

JNIEnv接口函数表中的索引13。

参数:

env :JNI接口指针。

obj :一个java.lang.Throwable对象。

返回值:

成功时返回0; 失败的负​​值。

抛出:

java.lang.Throwable object obj .

ThrowNew

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

使用message指定的message从指定的类构造一个异常对象,并导致抛出该异常。

连锁:

JNIEnv接口函数表中的索引14。

参数:

env :JNI接口指针。

clazz : clazz的子类。

message :用于构造java.lang.Throwable对象的消息。 该字符串以修改后的UTF-8编码。

返回值:

成功时返回0; 失败的负​​值。

抛出:

新构造的java.lang.Throwable对象。

ExceptionOccurred

jthrowable ExceptionOccurred(JNIEnv *env);

确定是否抛出异常。 在本机代码调用ExceptionClear()或Java代码处理异常之前,异常会一直抛出。

连锁:

JNIEnv接口函数表中的索引15。

参数:

env :JNI接口指针。

返回值:

返回当前正在抛出的异常对象,如果当前没有抛出异常,则返回NULL 。

ExceptionDescribe

void ExceptionDescribe(JNIEnv *env);

将堆栈的异常和回溯打印到系统错误报告通道,例如stderr 。 这是为调试提供的便利例程。

连锁:

JNIEnv接口函数表中的索引16。

参数:

env :JNI接口指针。

ExceptionClear

void ExceptionClear(JNIEnv *env);

清除当前正在抛出的任何异常。 如果当前没有抛出异常,则此例程无效。

连锁:

JNIEnv接口函数表中的索引17。

参数:

env :JNI接口指针。

致命错误

void FatalError(JNIEnv *env, const char *msg);

引发致命错误,并且不希望VM恢复。 此功能不返回。

连锁:

JNIEnv接口函数表中的索引18。

参数:

env :JNI接口指针。

msg :错误消息。 该字符串以修改后的UTF-8编码。

ExceptionCheck

我们引入了一个便捷函数来检查挂起的异常,而不创建对异常对象的本地引用。

jboolean ExceptionCheck(JNIEnv *env);

存在挂起异常时返回JNI_TRUE ; 否则,返回JNI_FALSE 。

连锁:

JNIEnv接口函数表中的索引228。

以来:

JDK / JRE 1.2

全球和本地参考

全球参考

NewGlobalRef

jobject NewGlobalRef(JNIEnv *env, jobject obj);

创建对obj参数引用的对象的新全局引用。 obj参数可以是全局或本地引用。 必须通过调用DeleteGlobalRef()显式处理全局引用。

连锁:

JNIEnv接口函数表中的索引21。

参数:

env :JNI接口指针。

obj :全局或本地引用。

返回值:

返回全局引用,如果系统内存不足,则返回NULL 。

DeleteGlobalRef

void DeleteGlobalRef(JNIEnv *env, jobject globalRef);

删除globalRef指向的全局引用。

连锁:

JNIEnv接口函数表中的索引22。

参数:

env :JNI接口指针。

globalRef :全局参考。

本地参考

本地引用在本机方法调用的持续时间内有效。 它们在本机方法返回后自动释放。 每个本地引用都会花费一定量的Java虚拟机资源。 程序员需要确保本机方法不会过度分配本地引用。 尽管在本机方法返回到Java之后会自动释放本地引用,但过度分配本地引用可能会导致VM在执行本机方法期间耗尽内存。

DeleteLocalRef

void DeleteLocalRef(JNIEnv *env, jobject localRef);

删除localRef指向的本地引用。

连锁:

JNIEnv接口函数表中的索引23。

参数:

env :JNI接口指针。

localRef :本地引用。

注意 :JDK / JRE 1.1提供了上面的DeleteLocalRef函数,以便程序员可以手动删除本地引用。 例如,如果本机代码遍历可能很大的对象数组并在每次迭代中使用一个元素,那么在创建新的本地引用之前删除对不再使用的数组元素的本地引用是一个好习惯。下一次迭代。

从JDK / JRE 1.2开始,为本地参考生命周期管理提供了一组额外的功能。 它们是下面列出的四个功能。

EnsureLocalCapacity

jint EnsureLocalCapacity(JNIEnv *env, jint capacity);

确保在当前线程中至少可以创建给定数量的本地引用。 成功时返回0; 否则返回一个负数并抛出一个OutOfMemoryError 。

在进入本机方法之前,VM会自动确保至少可以创建16个本地引用。

为了向后兼容,VM分配超出确保容量的本地引用。 (作为调试支持,VM可能会向用户发出警告,指出正在创建太多本地引用。在JDK中,程序员可以提供-verbose:jni命令行选项来打开这些消息。)VM调用FatalError if除了确保的容量之外,不能再创建本地引用。

连锁:

JNIEnv接口函数表中的索引26。

以来:

JDK / JRE 1.2

PushLocalFrame

jint PushLocalFrame(JNIEnv *env, jint capacity);

创建一个新的本地参考框架,其中至少可以创建给定数量的本地参考。 成功时返回0,失败时返回负数和挂起的OutOfMemoryError 。

请注意,已在先前本地帧中创建的本地引用在当前本地帧中仍然有效。

连锁:

JNIEnv接口函数表中的索引19。

以来:

JDK / JRE 1.2

PopLocalFrame

jobject PopLocalFrame(JNIEnv *env, jobject result);

弹出当前本地引用框架,释放所有本地引用,并在给定result对象的先前本地引用框架中返回本地引用。

如果您不需要返回对前一帧的引用,则将NULL作为result传递。

连锁:

JNIEnv接口函数表中的索引20。

以来:

JDK / JRE 1.2

NewLocalRef

jobject NewLocalRef(JNIEnv *env, jobject ref);

创建一个引用与ref相同的对象的新本地引用。 给定的ref可以是全局或本地引用。 如果ref引用null则返回NULL 。

连锁:

JNIEnv接口函数表中的索引25。

以来:

JDK / JRE 1.2

弱全球参考

弱全局引用是一种特殊的全局引用。 与普通的全局引用不同,弱全局引用允许对底层Java对象进行垃圾回收。 在使用全局或本地引用的任何情况下都可以使用弱全局引用。 当垃圾收集器运行时,如果该对象仅由弱引用引用,则它释放底层对象。 指向释放对象的弱全局引用在功能上等效于NULL 。 程序员可以通过使用IsSameObject将弱引用与NULL进行比较来检测弱全局引用是否指向释放的对象。

JNI中的弱全局引用是Java Weak References的简化版本,可作为Java 2 Platform API( java.lang.ref包及其类)的一部分提供。

澄清 (2001年6月增加)

由于在本机方法运行时可能会发生垃圾收集,因此可以随时释放由弱全局引用引用的对象。 虽然可以在使用全局引用的地方使用弱全局引用,但这样做通常是不合适的,因为它们可能在功能上等同于 NULL 而不另行通知。

虽然 IsSameObject 可用于确定弱全局引用是否引用已释放的对象,但它不会阻止此对象立即被释放。 因此,程序员可能不依赖此检查来确定 在将来的任何JNI函数调用中 是否可以使用弱全局引用(作为非 NULL 引用)。

为了克服这种固有的限制,建议使用JNI函数 NewLocalRef  NewGlobalRef 获取对同一对象的标准(强)本地或全局引用 ,并使用此强引用来访问目标对象。 如果对象已被释放, 这些函数将返回 NULL ,否则将返回强引用(这将阻止对象被释放)。 当不再需要立即访问对象时,应该显式删除新引用,从而允许释放该对象。

弱全局引用弱于其他类型的弱引用(SoftReference或WeakReference类的Java对象)。 在引用 同一特定对象的SoftReference或WeakReference对象清除其引用之前 ,对特定对象的弱全局引用在功能上不会等效于 NULL 

弱全局引用弱于Java对需要完成的对象的内部引用。 在完成引用对象的终结器(如果存在)之后, 弱全局引用将不会在功能上等效于 NULL 

弱全局引用和PhantomReferences之间的交互未定义。 特别地,Java VM的实现可以(或可以不)在PhantomReferences之后处理弱全局引用,并且它可以(或可以不)使用弱全局引用来保持也由PhantomReference对象引用的对象。 应避免使用弱全局引用的未定义。

NewWeakGlobalRef

jweak NewWeakGlobalRef(JNIEnv *env, jobject obj);

创建一个新的弱全局引用。 如果obj引用null ,或者VM内存不足,则返回NULL 。 如果VM内存不足,将抛出OutOfMemoryError 。

连锁:

JNIEnv接口函数表中的索引226。

以来:

JDK / JRE 1.2

DeleteWeakGlobalRef

void DeleteWeakGlobalRef(JNIEnv *env, jweak obj);

删除给定的弱全局引用所需的VM资源。

连锁:

JNIEnv接口函数表中的索引227。

以来:

JDK / JRE 1.2

对象操作

AllocObject

jobject AllocObject(JNIEnv *env, jclass clazz);

在不调用对象的任何构造函数的情况下分配新的Java对象。 返回对象的引用。

clazz参数不能引用数组类。

连锁:

JNIEnv接口函数表中的索引27。

参数:

env :JNI接口指针。

clazz :一个Java类对象。

返回值:

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

抛出:

InstantiationException :如果类是接口或抽象类。

OutOfMemoryError :如果系统内存不足。

NewObject,NewObjectA,NewObjectV

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

jobject NewObjectA(JNIEnv *env, jclass clazz, 
jmethodID methodID, const jvalue *args);

jobject NewObjectV(JNIEnv *env, jclass clazz, 
jmethodID methodID, va_list args);

构造一个新的Java对象。 方法ID指示要调用的构造方法。 必须通过调用GetMethodID()并使用<init>作为方法名称并将void ( V )作为返回类型来获取此ID。

clazz参数不能引用数组类。

NewObject的

程序员将所有要传递给构造函数的参数紧跟在methodID参数之后。 NewObject()接受这些参数并将它们传递给程序员希望调用的Java方法。

连锁:

JNIEnv接口函数表中的索引28。

NewObjectA

程序员将所有要传递给构造函数的args jvalues紧跟在methodID参数之后的jvaluesargs数组中。 NewObjectA()接受此数组中的参数,然后将它们传递给程序员希望调用的Java方法。

连锁:

JNIEnv接口函数表中的索引30。

NewObjectV的

程序员将所有要传递给构造函数的args放在紧跟在methodID参数之后的类型为va_listargs参数中。 NewObjectV()接受这些参数,然后将它们传递给程序员希望调用的Java方法。

连锁:

JNIEnv接口函数表中的索引29。

参数:

env :JNI接口指针。

clazz :一个Java类对象。

methodID :构造函数的方法ID。

NewObject的附加参数:

构造函数的参数。

NewObjectA的附加参数:

args :构造函数的参数数组。

NewObjectV的附加参数:

args :构造函数的参数的va_list。

返回值:

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

抛出:

InstantiationException :如果类是接口或抽象类。

OutOfMemoryError :如果系统内存不足。

构造函数抛出的任何异常。

GetObjectClass

jclass GetObjectClass(JNIEnv *env, jobject obj);

返回对象的类。

连锁:

JNIEnv接口函数表中的索引31。

参数:

env :JNI接口指针。

obj :一个Java对象(不能为NULL )。

返回值:

返回Java类对象。

GetObjectRefType

jobjectRefType GetObjectRefType(JNIEnv* env, jobject obj);

返回obj参数引用的对象的类型。 参数obj可以是本地,全局或弱全局引用。

连锁:

JNIEnv接口函数表中的索引232。

参数:

env :JNI接口指针。

obj :本地,全球或弱全球参考。 

vm :将从中检索接口的虚拟机实例。 

env :指向当前线程的JNI接口指针所在位置的指针。 

version :请求的JNI版本。

返回值:

函数GetObjectRefType返回以下定义为jobjectRefType枚举值jobjectRefType :

JNIInvalidRefType = 0, 
JNILocalRefType = 1, 
JNIGlobalRefType = 2, 
JNIWeakGlobalRefType = 3

如果参数obj是弱全局引用类型,则返回将为JNIWeakGlobalRefType 。

如果参数obj是全局引用类型,则返回值将为JNIGlobalRefType 。

如果参数obj是本地引用类型,则返回将为JNILocalRefType 。

如果obj参数不是有效引用,则此函数的返回值将为JNIInvalidRefType 。

无效引用是不是有效句柄的引用。 也就是说, obj指针地址不指向已从Ref创建函数之一分配或从JNI函数返回的存储器中的位置。

因此, NULL将是无效引用, GetObjectRefType(env,NULL)将返回JNIInvalidRefType 。

另一方面,null引用(指向null的引用)将返回最初创建null引用的引用类型。

GetObjectRefType不能用于已删除的引用。

由于引用通常实现为指向内存数据结构的指针,这些内存数据结构可能被VM中的任何引用分配服务重用,因此一旦删除,就不会指定GetObjectRefType将返回什么值。

以来:

JDK / JRE 1.6

IsInstanceOf

jboolean IsInstanceOf(JNIEnv *env, jobject obj, 
jclass clazz);

测试对象是否是类的实例。

连锁:

JNIEnv接口函数表中的索引32。

参数:

env :JNI接口指针。

obj :一个Java对象。

clazz :一个Java类对象。

返回值:

如果obj可以转换为clazz ,则返回JNI_TRUE ; 否则,返回JNI_FALSE 。 可以将NULL对象强制转换为任何类。

IsSameObject

jboolean IsSameObject(JNIEnv *env, jobject ref1, 
jobject ref2);

测试两个引用是否引用相同的Java对象。

连锁:

JNIEnv接口函数表中的索引24。

参数:

env :JNI接口指针。

ref1 :一个Java对象。

ref2 :一个Java对象。

返回值:

如果ref1ref2引用相同的Java对象,则返回JNI_TRUE ,或者都是NULL ; 否则,返回JNI_FALSE 。

访问对象的字段

GetFieldID

jfieldID GetFieldID(JNIEnv *env, jclass clazz, 
const char *name, const char *sig);

返回类的实例(非静态)字段的字段ID。 该字段由其名称和签名指定。 访问者函数的Get <type> FieldSet <type>字段系列使用字段ID来检索对象字段。

GetFieldID()导致初始化未初始化的类。

GetFieldID()不能用于获取数组的长度字段。 请改用GetArrayLength() 。

连锁:

JNIEnv接口函数表中的索引94。

参数:

env :JNI接口指针。

clazz :一个Java类对象。

name :以0结尾的修改后的UTF-8字符串中的字段名称。

sig :0终止修改的UTF-8字符串中的字段签名。

返回值:

返回字段ID,如果操作失败,则返回NULL 。

抛出:

NoSuchFieldError :如果找不到指定的字段。

ExceptionInInitializerError :如果类初始化程序因异常而失败。

OutOfMemoryError :如果系统内存不足。

Get<type> Field Routines

NativeType 获取<type>字段 (JNIEnv *env, jobject obj, 
jfieldID fieldID);
 (JNIEnv *env, jobject obj, 
jfieldID fieldID);

此系列的访问器例程返回对象的实例(非静态)字段的值。 要访问的字段由通过调用GetFieldID()获得的字段ID指定。

下表描述了Get <type> Field例程名称和结果类型。 您应该使用字段的Java类型替换Get <type> Field中的type,或者使用表中的一个实际例程名称,并将NativeType替换为该例程的相应本机类型。

获取<type>字段系列的访问程序例程
获取<type>字段例程名称 原生类型
GetObjectField() jobject
GetBooleanField() jboolean
GetByteField() jbyte
GetCharField() jchar
GetShortField() jshort
GetIntField() jint
GetLongField() jlong
GetFloatField() jfloat
GetDoubleField() jdouble

连锁:

JNIEnv接口函数表中的索引:

获取<type>字段系列的访问程序例程
获取<type>字段例程名称 指数
GetObjectField() 95
GetBooleanField() 96
GetByteField() 97
GetCharField() 98
GetShortField() 99
GetIntField() 100
GetLongField() 101
GetFloatField() 102
GetDoubleField() 103

参数:

env :JNI接口指针。

obj :一个Java对象(不能为NULL )。

fieldID :有效的字段ID。

返回值:

返回字段的内容。

Set<type> Field Routines

void Set<type>Field(JNIEnv *env, jobject obj, jfieldID fieldID,
NativeType value);

此系列的访问器例程设置对象的实例(非静态)字段的值。 要访问的字段由通过调用GetFieldID()获得的字段ID指定。

下表描述了Set <type> Field例程名称和值类型。 您应该将Set <type> Field中的type替换 字段的Java类型,或者使用表中的一个实际例程名称,并将NativeType替换为该例程的相应本机类型。

设置<type>字段系列的访问程序例程
设置<type> Field Routine 原生类型
SetObjectField() jobject
etBooleanField() jboolean
SetByteField() jbyte
SetCharField() jchar
SetShortField() jshort
SetIntField() jint
SetLongField() jlong
SetFloatField() jfloat
SetDoubleField() jdouble

连锁:

JNIEnv接口函数表中的索引。

设置<type>字段系列的访问程序例程
设置<type> Field Routine 指数
SetObjectField() 104
etBooleanField() 105
SetByteField() 106
SetCharField() 107
SetShortField() 108
SetIntField() 109
SetLongField() 110
SetFloatField() 111
SetDoubleField() 112

参数:

env :JNI接口指针。

obj :一个Java对象(不能为NULL )。

fieldID :有效的字段ID。

value :字段的新值。

调用实例方法

的GetMethodID

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

返回类或接口的实例(非静态)方法的方法ID。 该方法可以在clazz的一个超类中定义,并由clazz继承。 该方法由其名称和签名确定。

GetMethodID()导致初始化未初始化的类。

要获取构造函数的方法ID,请提供<init>作为方法名称,并将void ( V )作为返回类型。

连锁:

JNIEnv接口函数表中的索引33。

参数:

env :JNI接口指针。

clazz :一个Java类对象。

name :以0结尾的修改后的UTF-8字符串中的方法名称。

sig :0终止修改的UTF-8字符串中的方法签名。

返回值:

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

抛出:

NoSuchMethodError :如果找不到指定的方法。

ExceptionInInitializerError :如果类初始化程序因异常而失败。

OutOfMemoryError :如果系统内存不足。

Call<type>Method Routines, Call<type>MethodA Routines, Call<type>MethodV Routines

NativeType Call<type>Method(JNIEnv *env, jobject obj,
jmethodID methodID, ...);

NativeType Call<type>MethodA(JNIEnv *env, jobject obj,
jmethodID methodID, const jvalue *args);

NativeType Call<type>MethodV(JNIEnv *env, jobject obj,
jmethodID methodID, va_list args);

来自这三个操作系列的方法用于从本机方法调用Java实例方法。它们只是将参数传递给它们调用的方法的机制不同。

这些操作系列根据指定的方法ID在Java对象上调用实例(非静态)方法。 必须通过调用GetMethodID ()获取methodID参数。

当这些函数用于调用私有方法和构造函数时,方法ID必须从obj的真实类派生,而不是从其超类之一派生。

Call<type>Method 方法例程

程序员将所有要传递给方法的参数紧跟在methodID参数之后。 Call <type> Method例程接受这些参数并将它们传递给程序员希望调用的Java方法。

Call<type>Method  MethodA Routines

程序员将方法的所有参数jvalues紧跟在methodID参数之后的jvaluesargs数组中。 Call <type> MethodA例程接受此数组中的参数,然后将它们传递给程序员希望调用的Java方法。

Call<type> MethodV Routines

程序员将方法的所有参数放在紧跟在methodID参数之后的类型为va_listargs参数中。 Call <type> MethodV例程接受参数,然后将它们传递给程序员希望调用的Java方法。

下表根据结果类型描述了每个方法调用例程。 您应该将Call <type> Method中的type替换为您正在调用的方法的Java类型(或使用表中实际的方法调用例程名称之一),并将NativeType替换为该例程的相应本机类型。

实例方法调用例程
调用<type>方法例程名称 原生类型
CallVoidMethod() CallVoidMethodA() CallVoidMethodV() 空虚
CallObjectMethod() CallObjectMethodA() CallObjectMethodV() jobject
CallBooleanMethod() CallBooleanMethodA() CallBooleanMethodV() jboolean
CallByteMethod() CallByteMethodA() CallByteMethodV() jbyte
CallCharMethod() CallCharMethodA() CallCharMethodV() jchar
CallShortMethod() CallShortMethodA() CallShortMethodV() jshort
CallIntMethod() CallIntMethodA() CallIntMethodV() jint
CallLongMethod() CallLongMethodA() CallLongMethodV() jlong
CallFloatMethod() CallFloatMethodA() CallFloatMethodV() jfloat
CallDoubleMethod() CallDoubleMethodA() CallDoubleMethodV() jdouble

连锁:

JNIEnv接口函数表中的索引:

实例方法调用例程
调用<type>方法例程名称 指数
CallVoidMethod() CallVoidMethodA() CallVoidMethodV()

61 
63 
62

CallObjectMethod() CallObjectMethodA() CallObjectMethodV()

34 
36 
35

CallBooleanMethod() CallBooleanMethodA() CallBooleanMethodV()

37 
39 
38

CallByteMethod() CallByteMethodA() CallByteMethodV()

40 
42 
41

CallCharMethod() CallCharMethodA() CallCharMethodV()

43 
45 
44

CallShortMethod() CallShortMethodA() CallShortMethodV()

46 
48 
47

CallIntMethod() CallIntMethodA() CallIntMethodV()

49 
51 
50

CallLongMethod() CallLongMethodA() CallLongMethodV()

52 
54 
53

CallFloatMethod() CallFloatMethodA() CallFloatMethodV()

55 
57 
56

CallDoubleMethod() CallDoubleMethodA() CallDoubleMethodV()

58 
60 
59

参数:

env :JNI接口指针。

obj :一个Java对象。

methodID :方法ID。

Call <type>方法例程的附加参数:

Java方法的参数。

Call <type> MethodA例程的附加参数:

args :一组参数。

Call <type> MethodV例程的附加参数:

args :一个参数的va_list。

返回值:

返回调用Java方法的结果。

抛出:

Exceptions raised during the execution of the Java method.

CallNonvirtual <type> Method Routines,CallNonvirtual <type> MethodA Routines,CallNonvirtual <type> MethodV Routines

NativeType CallNonvirtual <type>Method (JNIEnv *env, jobject obj, 
jclass clazz, jmethodID methodID, ...);

NativeType CallNonvirtual <type> MethodA (JNIEnv *env, jobject obj, 
jclass clazz, jmethodID methodID, const jvalue *args);

NativeType CallNonvirtual <type> MethodV (JNIEnv *env, jobject obj, 
jclass clazz, jmethodID methodID, va_list args);

这些操作系列根据指定的类和方法ID在Java对象上调用实例(非静态)方法。该methodID参数必须通过调用获得GetMethodID ()的类clazz

所述CallNonvirtual <类型>方法例程的家庭和呼叫<类型>方法例程的家庭是不同的。调用<type>方法例程根据对象的类调用方法,而CallNonvirtual <type> Method例程根据clazz参数指定的类调用方法,从中获取方法ID。方法ID必须从对象的真实类或其超类之一获得。

CallNonvirtual <type> Method Routines

程序员将所有要传递给参数的参数放在参数后面methodID。所述CallNonvirtual <类型>方法例程接受这些参数并将其传给编程人员所要调用的Java方法。

CallNonvirtual <type> MethodA例程

程序员将方法的所有参数放在紧跟在参数后面的args数组中。所述CallNonvirtual <类型>方法a routine接受这些参数这个阵列中,并且,反过来,其传给编程人员所要调用的Java方法。jvaluesmethodID

CallNonvirtual <type> MethodV Routines

程序员将方法的所有参数放在紧跟在参数args后面的类型va_listmethodID参数中。该CallNonvirtualMethodV routine接受这些参数,并且,反过来,它们传给编程人员所要调用的Java方法。

下表根据结果类型描述了每个方法调用例程。此时应更换CallNonvirtual <类型>方法的Java类型的方法,或者使用的实际方法从表中调用例程的名字之一,并取代本地类型与对应的原生类型,常规。

CallNonvirtual <type> Method Routines
CallNonvirtual <type> Method Routine Name 原生类型
CallNonvirtualVoidMethod() CallNonvirtualVoidMethodA() CallNonvirtualVoidMethodV() 空虚
CallNonvirtualObjectMethod() CallNonvirtualObjectMethodA() CallNonvirtualObjectMethodV() jobject
CallNonvirtualBooleanMethod() CallNonvirtualBooleanMethodA() CallNonvirtualBooleanMethodV() jboolean
CallNonvirtualByteMethod() CallNonvirtualByteMethodA() CallNonvirtualByteMethodV() jbyte
CallNonvirtualCharMethod() CallNonvirtualCharMethodA() CallNonvirtualCharMethodV() jchar
CallNonvirtualShortMethod() CallNonvirtualShortMethodA() CallNonvirtualShortMethodV() jshort
CallNonvirtualIntMethod() CallNonvirtualIntMethodA() CallNonvirtualIntMethodV() jint
CallNonvirtualLongMethod() CallNonvirtualLongMethodA() CallNonvirtualLongMethodV() jlong
CallNonvirtualFloatMethod() CallNonvirtualFloatMethodA() CallNonvirtualFloatMethodV() jfloat
CallNonvirtualDoubleMethod() CallNonvirtualDoubleMethodA() CallNonvirtualDoubleMethodV() jdouble

连锁:

JNIEnv接口函数表中的索引。

CallNonvirtual <type> Method Routines
CallNonvirtual <type> Method Routine Name 指数
CallNonvirtualVoidMethod() CallNonvirtualVoidMethodA() CallNonvirtualVoidMethodV() 91 
93 
92
CallNonvirtualObjectMethod() CallNonvirtualObjectMethodA() CallNonvirtualObjectMethodV() 64 
66 
65
CallNonvirtualBooleanMethod() CallNonvirtualBooleanMethodA() CallNonvirtualBooleanMethodV() 67 
69 
68
CallNonvirtualByteMethod() CallNonvirtualByteMethodA() CallNonvirtualByteMethodV() 70 
72 
71
CallNonvirtualCharMethod() CallNonvirtualCharMethodA() CallNonvirtualCharMethodV() 73 
75 
74
CallNonvirtualShortMethod() CallNonvirtualShortMethodA() CallNonvirtualShortMethodV() 76 
78 
77
CallNonvirtualIntMethod() CallNonvirtualIntMethodA() CallNonvirtualIntMethodV() 79 
81 
80
CallNonvirtualLongMethod() CallNonvirtualLongMethodA() CallNonvirtualLongMethodV() 82 
84 
83
CallNonvirtualFloatMethod() CallNonvirtualFloatMethodA() CallNonvirtualFloatMethodV() 85 
87 
86
CallNonvirtualDoubleMethod() CallNonvirtualDoubleMethodA() CallNonvirtualDoubleMethodV() 88 
90 
89

参数:

env :JNI接口指针。

clazz: a Java类。

obj :一个Java对象。

methodID :方法ID。

CallNonvirtual <type>方法例程的附加参数:

Java方法的参数。

CallNonvirtual <type> MethodA例程的附加参数:

args :一组参数。

CallNonvirtual <type> MethodV例程的附加参数:

args:一个va_list论点。

返回值:

返回调用Java方法的结果。

抛出:

执行Java方法期间引发的异常。

访问静态字段

GetStaticFieldID

jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, 
const char *name, const char *sig);

返回类的静态字段的字段ID。该字段由其名称和签名指定。所述GetStatic <类型>字段SetStatic <类型>字段的存取器函数系列使用域ID来检索静态字段。

GetStaticFieldID() 导致未初始化的类被初始化。

连锁:

JNIEnv接口函数表中的索引144。

参数:

env :JNI接口指针。

clazz :Java类对象。

name :0终止修改的UTF-8字符串中的静态字段名称。

sig :0终止修改的UTF-8字符串中的字段签名。

返回值:

返回字段ID,或者NULL如果找不到指定的静态字段。

抛出:

NoSuchFieldError :如果找不到指定的静态字段。

ExceptionInInitializerError :如果类初始值设定项因异常而失败。

OutOfMemoryError :如果系统内存不足。

GetStatic <type> Field Routines

NativeType GetStatic <type> Field (JNIEnv *env, jclass clazz, 
jfieldID fieldID);

这个访问器例程系列返回对象的静态字段的值。要访问的字段由字段ID指定,该字段ID是通过调用获得的GetStaticFieldID()

下表描述了get例程名称和结果类型的系列。此时应更换GetStatic <类型>字段的Java类型的字段,或者从表中的实际静态字段访问例程名,并替换本地类型与对应的原生类型,常规。

GetStatic <type>字段系列的Accessor例程
GetStatic <type>字段例程名称 原生类型
GetStaticObjectField () jobject
GetStaticBooleanField () jboolean
GetStaticByteField () jbyte
GetStaticCharField () jchar
GetStaticShortField () jshort
GetStaticIntField () jint
GetStaticLongField () jlong
GetStaticFloatField () jfloat
GetStaticDoubleField () jdouble

连锁:

JNIEnv接口函数表中的索引。

GetStatic <type>字段系列的Accessor例程
GetStatic <type>字段例程名称 指数
GetStaticObjectField () 145
GetStaticBooleanField () 146
GetStaticByteField () 147
GetStaticCharField () 148
GetStaticShortField () 149
GetStaticIntField () 150
GetStaticLongField () 151
GetStaticFloatField () 152
GetStaticDoubleField () 153

参数:

env :JNI接口指针。

clazz :Java类对象。

fieldID :静态字段ID。

返回值:

返回静态字段的内容。

GetStatic <type> Field Routines

NativeType GetStatic <type> Field (JNIEnv *env, jclass clazz, 
jfieldID fieldID);

这个访问器例程系列返回对象的静态字段的值。要访问的字段由字段ID指定,该字段ID是通过调用获得的GetStaticFieldID()

下表描述了get例程名称和结果类型的系列。此时应更换GetStatic <类型>字段的Java类型的字段,或者从表中的实际静态字段访问例程名,并替换本地类型与对应的原生类型,常规。

GetStatic <type>字段系列的Accessor例程
GetStatic <type>字段例程名称 原生类型
GetStaticObjectField () jobject
GetStaticBooleanField () jboolean
GetStaticByteField () jbyte
GetStaticCharField () jchar
GetStaticShortField () jshort
GetStaticIntField () jint
GetStaticLongField () jlong
GetStaticFloatField () jfloat
GetStaticDoubleField () jdouble

连锁:

JNIEnv接口函数表中的索引。

GetStatic <type>字段系列的Accessor例程
GetStatic <type>字段例程名称 指数
GetStaticObjectField () 145
GetStaticBooleanField () 146
GetStaticByteField () 147
GetStaticCharField () 148
GetStaticShortField () 149
GetStaticIntField () 150
GetStaticLongField () 151
GetStaticFloatField () 152
GetStaticDoubleField () 153

参数:

env :JNI接口指针。

clazz :Java类对象。

fieldID :静态字段ID。

返回值:

返回静态字段的内容。

SetStatic <type> Field Routines

void SetStatic <type> Field NativeType(JNIEnv *env, jclass clazz, 
jfieldID fieldID,
 value);

这个访问器例程系列设置对象的静态字段的值。要访问的字段由字段ID指定,该字段ID是通过调用获得的GetStaticFieldID()

下表描述了set例程名称和值类型。此时应更换SetStatic <类型>字段的Java类型的字段,或从表中实际设置静态字段例程名,并替换本地类型与对应的原生类型,常规。

SetStatic <type>字段系列的Accessor例程
SetStatic <type>字段例程名称 本地类型
SetStaticObjectField () jobject
SetStaticBooleanField () jboolean
SetStaticByteField () jbyte
SetStaticCharField () jchar
SetStaticShortField () jshort
SetStaticIntField () jint
SetStaticLongField () jlong
SetStaticFloatField () jfloat
SetStaticDoubleField () jdouble

连锁:

JNIEnv接口函数表中的索引。

SetStatic <type>字段系列的Accessor例程
SetStatic <type>字段例程名称 指数
SetStaticObjectField () 154
SetStaticBooleanField () 155
SetStaticByteField () 156
SetStaticCharField () 157
SetStaticShortField () 158
SetStaticIntField () 159
SetStaticLongField () 160
SetStaticFloatField () 161
SetStaticDoubleField () 162

参数:

env :JNI接口指针。

clazz :Java类对象。

fieldID :静态字段ID。

value :该领域的新价值。

调用静态方法

GetStaticMethodID

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

返回类的静态方法的方法ID。该方法由其名称和签名指定。

GetStaticMethodID() 导致未初始化的类被初始化。

连锁:

JNIEnv接口函数表中的索引113。

参数:

env :JNI接口指针。

clazz :Java类对象。

name :0终止的修改的UTF-8字符串中的静态方法名称。

sig :0终止修改的UTF-8字符串中的方法签名。

返回值:

返回方法ID,或者NULL操作失败。

抛出:

NoSuchMethodError :如果找不到指定的静态方法。

ExceptionInInitializerError :如果类初始值设定项因异常而失败。

OutOfMemoryError :如果系统内存不足。

CallStatic <type> Method Routines,CallStatic <type> MethodA Routines,CallStatic <type> MethodV Routines

NativeType CallStatic <type>方法 (JNIEnv *env, jclass clazz, 
jmethodID methodID, ...);

NativeType CallStatic <type> MethodA (JNIEnv *env, jclass clazz, 
jmethodID methodID, jvalue *args);

NativeType CallStatic <type> MethodV (JNIEnv *env, jclass clazz, 
jmethodID methodID, va_list args);

此系列操作根据指定的方法ID在Java对象上调用静态方法。该methodID参数必须通过调用来获得GetStaticMethodID ()

方法ID必须来自clazz,而不是来自其超类之一。

CallStatic <type> Method Routines

程序员应该在参数后面立即放置要传递给方法的所有methodID参数。所述CallStatic <类型>方法例程接受这些参数并将其传给编程人员所要调用的Java方法。

CallStatic <type> MethodA Routines

程序员应该将方法的所有参数放在紧跟在参数后面的args数组中。所述CallStaticMethodA例程接受此阵列中的参数,并且,反过来,其传给编程人员所要调用的Java方法。jvaluesmethodID

CallStatic <type> MethodV例程

程序员应该将方法的所有参数放在紧跟在参数args后面的类型va_listmethodID参数中。该CallStaticMethodV routine接受这些参数,并且,反过来,它们传给编程人员所要调用的Java方法。

下表根据结果类型描述了每个方法调用例程。此时应更换CallStatic <类型>方法的Java类型的方法,或实际方法从表中调用例程的名字之一,并取代本地类型与对应的原生类型,常规。

CallStatic <type>方法调用例程
CallStatic <type> Method Routine Name 原生类型
CallStaticVoidMethod () CallStaticVoidMethodA () CallStaticVoidMethod V() 空虚
CallStaticObjectMethod () CallStaticObjectMethod A() CallStaticObjectMethod V() jobject
CallStaticBooleanMethod () CallStaticBooleanMethod A() CallStaticBooleanMethod V() jboolean
CallStaticByteMethod () CallStaticByteMethod A() CallStaticByteMethod V() jbyte
CallStaticCharMethod () CallStaticCharMethod A() CallStaticCharMethod V() jchar
CallStaticShortMethod () CallStaticShortMethod A() CallStaticShortMethod V() jshort
CallStaticIntMethod () CallStaticIntMethod A() CallStaticIntMethod V() jint
CallStaticLongMethod () CallStaticLongMethod A() CallStaticLongMethod V() jlong
CallStaticFloatMethod () CallStaticFloatMethod A() CallStaticFloatMethod V() jfloat
CallStaticDoubleMethod () CallStaticDoubleMethod A() CallStaticDoubleMethod V() jdouble

连锁:

JNIEnv接口函数表中的索引。

CallStatic <type>方法调用例程
CallStatic <type> Method Routine Name 指数
CallStaticVoidMethod () CallStaticVoidMethodA () CallStaticVoidMethod V() 141 
143 
142
CallStaticObjectMethod () CallStaticObjectMethod A() CallStaticObjectMethod V() 114 
116 
115
CallStaticBooleanMethod () CallStaticBooleanMethod A() CallStaticBooleanMethod V() 117 
119 
118
CallStaticByteMethod () CallStaticByteMethod A() CallStaticByteMethod V() 120 
122 
121
CallStaticCharMethod () CallStaticCharMethod A() CallStaticCharMethod V() 123 
125 
124
CallStaticShortMethod () CallStaticShortMethod A() CallStaticShortMethod V() 126 
128 
127
CallStaticIntMethod () CallStaticIntMethod A() CallStaticIntMethod V() 129 
131 
130
CallStaticLongMethod () CallStaticLongMethod A() CallStaticLongMethod V() 132 
134 
133
CallStaticFloatMethod () CallStaticFloatMethod A() CallStaticFloatMethod V() 135 
137 
136
CallStaticDoubleMethod () CallStaticDoubleMethod A() CallStaticDoubleMethod V() 138 
140 
139

参数:

env :JNI接口指针。

clazz :Java类对象。

methodID :静态方法ID。

CallStatic <type>方法例程的附加参数:

静态方法的参数。

CallStatic <type> MethodA例程的附加参数:

args :一组参数。

CallStatic <type> MethodV例程的附加参数:

args:一个va_list论点。

返回值:

返回调用静态Java方法的结果。

抛出:

Exceptions raised during the execution of the Java method.

字符串操作

NewString

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

java.lang.String从Unicode字符数组构造一个新对象。

连锁:

JNIEnv接口函数表中的索引163。

参数:

env :JNI接口指针。

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

len :Unicode字符串的长度。

返回值:

返回Java字符串对象,或者NULL无法构造字符串。

抛出:

OutOfMemoryError :如果系统内存不足。

GetStringLength

jsize GetStringLength(JNIEnv *env, jstring string);

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

连锁:

JNIEnv接口函数表中的索引164。

参数:

env :JNI接口指针。

string :Java字符串对象。

返回值:

返回Java字符串的长度。

GetStringChars

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

返回指向字符串的Unicode字符数组的指针。该指针在ReleaseStringChars()被调用之前有效。

如果isCopy不是NULL,则*isCopy设置为JNI_TRUE复制; 或者JNI_FALSE如果没有复制则设置为。

连锁:

JNIEnv接口函数表中的索引165。

参数:

env :JNI接口指针。

string :Java字符串对象。

isCopy :指向布尔值的指针。

返回值:

返回指向Unicode字符串的指针,或者NULL操作是否失败。

ReleaseStringChars

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

通知VM本机代码不再需要访问权限chars。该chars参数是从所获得的指针string使用GetStringChars()

连锁:

JNIEnv接口函数表中的索引166。

参数:

env :JNI接口指针。

string :Java字符串对象。

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

NewStringUTF

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

使用java.lang.String修改后的UTF-8编码从字符数组构造一个新对象。

连锁:

JNIEnv接口函数表中的索引167。

参数:

env :JNI接口指针。

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

返回值:

返回Java字符串对象,或者NULL无法构造字符串。

抛出:

OutOfMemoryError :如果系统内存不足。

GetStringUTFLength

jsize GetStringUTFLength(JNIEnv *env, jstring string);

返回字符串的修改后的UTF-8表示的字节长度。

连锁:

JNIEnv接口函数表中的索引168。

参数:

env :JNI接口指针。

string :Java字符串对象。

返回值:

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

GetStringUTFChars

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

返回指向字节数组的指针,该字节数组表示修改后的UTF-8编码中的字符串。此数组在释放之前有效ReleaseStringUTFChars()

如果isCopy不是NULL,则*isCopy设置为JNI_TRUE复制; 或者JNI_FALSE如果没有复制则设置为。

连锁:

JNIEnv接口函数表中的索引169。

参数:

env :JNI接口指针。

string :Java字符串对象。

isCopy :指向布尔值的指针。

返回值:

返回指向已修改的UTF-8字符串的指针,或者NULL操作是否失败。

ReleaseStringUTFChars

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

通知VM本机代码不再需要访问权限utf。该utf参数是从衍生的指针string使用GetStringUTFChars()

连锁:

JNIEnv接口函数表中的索引170。

参数:

env :JNI接口指针。

string :Java字符串对象。

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

注意:在JDK / JRE 1.1中,程序员可以在用户提供的缓冲区中获取原始数组元素。从JDK / JRE 1.2开始,提供了一组额外的功能,允许本机代码在用户提供的缓冲区中获取Unicode(UTF-16)或修改的UTF-8编码的字符。请参阅以下功能。

GetStringRegion

void GetStringRegion(JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf);

len将从偏移量开始的Unicode字符数复制start到给定缓冲区buf

引发StringIndexOutOfBoundsException索引溢出。

连锁:

JNIEnv接口函数表中的索引220。

以来:

JDK / JRE 1.2

GetStringUTFRegion

void GetStringUTFRegion(JNIEnv *env, jstring str, jsize start, jsize len, char *buf);

平移len偏移量开始的Unicode字符数start成改性UTF-8编码并将结果置于在给定的缓冲器buf

引发StringIndexOutOfBoundsException索引溢出。

连锁:

JNIEnv接口函数表中的索引221。

以来:

JDK / JRE 1.2

GetStringCritical,ReleaseStringCritical

const jchar * GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy); 
void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *carray);

这两个函数的语义类似于现有Get/ReleaseStringChars函数。如果可能,VM返回指向字符串元素的指针; 否则,制作副本。但是,如何使用这些功能存在重大限制。在由Get/ReleaseStringCritical调用包含的代码段中,本机代码不得发出任意JNI调用,或导致当前线程阻塞。

限制Get/ReleaseStringCritical与那些相似Get/ReleasePrimitiveArrayCritical

LINKAGE(GetStringCritical):

JNIEnv接口函数表中的索引224。

LINKAGE(ReleaseStingCritical):

JNIEnv接口函数表中的索引225。

以来:

JDK / JRE 1.2

阵列操作

GetArrayLength

jsize GetArrayLength(JNIEnv *env, jarray array);

返回数组中的元素数。

连锁:

JNIEnv接口函数表中的索引171。

参数:

env :JNI接口指针。

array :一个Java数组对象。

返回值:

返回数组的长度。

NewObjectArray

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

构造一个包含类中对象的新数组elementClass。所有元素最初都设置为initialElement

连锁:

JNIEnv接口函数表中的索引172。

参数:

env :JNI接口指针。

length :数组大小。

elementClass :数组元素类。

initialElement :初始化值。

返回值:

返回Java数组对象,或者NULL无法构造数组。

抛出:

OutOfMemoryError :如果系统内存不足。

GetObjectArrayElement

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

返回Object数组的元素。

连锁:

JNIEnv接口函数表中的索引173。

参数:

env :JNI接口指针。

array :一个Java数组。

index :数组索引。

返回值:

返回一个Java对象。

抛出:

ArrayIndexOutOfBoundsException:if如果index未在数组中指定有效索引。

SetObjectArrayElement

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

设置Object数组的元素。

连锁:

JNIEnv接口函数表中的索引174。

参数:

env :JNI接口指针。

array :一个Java数组。

index :数组索引。

value :新的价值。

抛出:

ArrayIndexOutOfBoundsException:if如果index未在数组中指定有效索引。

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

新的<PrimitiveType>数组例程

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

用于构造新原始数组对象的一系列操作。下表描述了特定的基本数组构造函数。您应该使用此表中的一个实际原始数组构造函数例程名称替换New <PrimitiveType> Array,并将ArrayType替换为该例程的相应数组类型。

新的<PrimitiveType>数组构造函数阵列
新的<PrimitiveType>数组例程 数组类型
NewBooleanArray() jbooleanArray
NewByteArray() jbyteArray
NewCharArray() jcharArray
NewShortArray() jshortArray
NewIntArray() jintArray
NewLongArray() jlong​​Array
NewFloatArray() jfloatArray
NewDoubleArray() jdoubleArray

连锁:

JNIEnv接口函数表中的索引。

新的<PrimitiveType>数组构造函数阵列
新的<PrimitiveType>数组例程 指数
NewBooleanArray() 175
NewByteArray() 176
NewCharArray() 177
NewShortArray() 178
NewIntArray() 179
NewLongArray() 180
NewFloatArray() 181
NewDoubleArray() 182

参数:

env :JNI接口指针。

length :数组长度。

返回值:

返回Java数组,或者NULL无法构造数组。

Get<PrimitiveType> ArrayElements例程

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

返回基本数组主体的一系列函数。结果有效,直到调用相应的Release < PrimitiveType > ArrayElements()函数。小号因斯返回的数组可能是Java数组的副本,因此对返回数组的更改不必反映在原始 array 直到Release<PrimitiveType>ArrayElements() 被调用。

如果isCopy不是NULL,则*isCopy设置为JNI_TRUE复制; 或者JNI_FALSE如果没有复制则设置为。

下表描述了特定的原始数组元素访问器。您应该进行以下替换:

  • Get <PrimitiveType> ArrayElements替换为下表中的一个实际原始元素访问器例程名称。
  • 将ArrayType替换为相应的数组类型。
  • NativeType替换为该例程的相应本机类型。

无论如何在Java VM中表示布尔数组,GetBooleanArrayElements()总是返回一个指向的指针jbooleans,每个字节表示一个元素(解包表示)。其他类型的所有数组都保证在内存中是连续的。

获取<PrimitiveType> ArrayElements Accessor例程系列
获取<PrimitiveType> ArrayElements例程 数组类型 原生类型
GetBooleanArrayElements() jbooleanArray jboolean
GetByteArrayElements() jbyteArray jbyte
GetCharArrayElements() jcharArray jchar
GetShortArrayElements() jshortArray jshort
GetIntArrayElements() jintArray jint
GetLongArrayElements() jlong​​Array jlong
GetFloatArrayElements() jfloatArray jfloat
GetDoubleArrayElements() jdoubleArray jdouble

连锁:

JNIEnv接口函数表中的索引。

获取<PrimitiveType> ArrayElements Accessor例程系列
获取<PrimitiveType> ArrayElements例程 指数
GetBooleanArrayElements() 183
GetByteArrayElements() 184
GetCharArrayElements() 185
GetShortArrayElements() 186
GetIntArrayElements() 187
GetLongArrayElements() 188
GetFloatArrayElements() 189
GetDoubleArrayElements() 190

参数:

env :JNI接口指针。

array :Java字符串对象。

isCopy :指向布尔值的指针。

返回值:

返回指向数组元素的指针,或者NULL操作是否失败。

发布<PrimitiveType> ArrayElements例程

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

一系列函数,用于通知VM本机代码不再需要访问elems。该elems参数是array使用相应的Get < PrimitiveType > ArrayElements()函数派生的指针。如有必要,此功能将复制elems对原始阵列所做的所有更改。

mode参数提供有关如何释放数组缓冲区的信息。mode如果elems不是元素的副本,则无效array。否则,mode会产生以下影响,如下表所示:

原始阵列发布模式
模式 行动
0 复制内容并释放elems缓冲区
JNI_COMMIT 复制内容但不释放elems缓冲区
JNI_ABORT 释放缓冲区而不复制可能的更改

在大多数情况下,程序员将“0”传递给mode参数,以确保固定和复制数组的一致行为。其他选项使程序员可以更好地控制内存管理,并且应该非常谨慎地使用。

下表描述了构成原始数组处理器系列的特定例程。您应该进行以下替换:

  • Release <PrimitiveType> ArrayElements替换为下表中的一个实际原始数组处理程序例程名称。
  • 将ArrayType替换为相应的数组类型。
  • NativeType替换为该例程的相应本机类型。
发布<PrimitiveType> ArrayElements数组例程系列
发布<PrimitiveType> ArrayElements例程 数组类型 原生类型
ReleaseBooleanArrayElements() jbooleanArray jboolean
ReleaseByteArrayElements() jbyteArray jbyte
ReleaseCharArrayElements() jcharArray jchar
ReleaseShortArrayElements() jshortArray jshort
ReleaseIntArrayElements() jintArray jint
ReleaseLongArrayElements() jlong​​Array jlong
ReleaseFloatArrayElements() jfloatArray jfloat
ReleaseDoubleArrayElements() jdoubleArray jdouble

连锁:

JNIEnv接口函数表中的索引。

发布<PrimitiveType> ArrayElements数组例程系列
发布<PrimitiveType> ArrayElements例程 指数
ReleaseBooleanArrayElements() 191
ReleaseByteArrayElements() 192
ReleaseCharArrayElements() 193
ReleaseShortArrayElements() 194
ReleaseIntArrayElements() 195
ReleaseLongArrayElements() 196
ReleaseFloatArrayElements() 197
ReleaseDoubleArrayElements() 198

参数:

env :JNI接口指针。

array :一个Java数组对象。

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

mode :发布模式。

获取<PrimitiveType> ArrayRegion例程

void 获取<PrimitiveType> ArrayRegion (JNIEnv *env, ArrayType NativeTypearray, 
jsize start, jsize len,
 *buf);

一系列函数,用于将基本数组的区域复制到缓冲区中。

下表描述了特定的原始数组元素访问器。你应该做以下替换:

  • Get <PrimitiveType> ArrayRegion替换为下表中的一个实际原始元素访问器例程名称。
  • ArrayType替换为相应的数组类型。
  • NativeType替换为该例程的相应本机类型。
获取<PrimitiveType> ArrayRegion系列数组访问器例程
获取<PrimitiveType> ArrayRegion例程 数组类型 原生类型
GetBooleanArrayRegion() jbooleanArray jboolean
GetByteArrayRegion() jbyteArray jbyte
GetCharArrayRegion() jcharArray jchar
GetShortArrayRegion() jshortArray jhort
GetIntArrayRegion() jintArray jint
GetLongArrayRegion() jlong​​Array jlong
GetFloatArrayRegion() jfloatArray jloat
GetDoubleArrayRegion() jdoubleArray jdouble

连锁:

JNIEnv接口函数表中的索引。

获取<PrimitiveType> ArrayRegion系列数组访问器例程

获取<PrimitiveType> ArrayRegion例程 指数
GetBooleanArrayRegion() 199
GetByteArrayRegion() 200
GetCharArrayRegion() 201
GetShortArrayRegion() 202
GetIntArrayRegion() 203
GetLongArrayRegion() 204
GetFloatArrayRegion() 205
GetDoubleArrayRegion() 206

参数:

env :JNI接口指针。

array :一个Java数组。

start :起始指数。

len :要复制的元素数。

buf :目标缓冲区。

抛出:

ArrayIndexOutOfBoundsException :如果该区域中的某个索引无效。

Set<PrimitiveType> ArrayRegion例程

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

一系列函数,用于从缓冲区复制基本数组的区域。

下表描述了特定的原始数组元素访问器。您应该进行以下替换:

  • Set <PrimitiveType> ArrayRegion替换为下表中的一个实际原始元素访问器例程名称。
  • 将ArrayType替换为相应的数组类型。
  • NativeType替换为该例程的相应本机类型。

Set<PrimitiveType> ArrayRegion系列数组访问器例程

设置<PrimitiveType> ArrayRegion Routine 数组类型 原生类型
SetBooleanArrayRegion() jbooleanArray jboolean
SetByteArrayRegion() jbyteArray jbyte
SetCharArrayRegion() jcharArray jchar
SetShortArrayRegion() jshortArray jshort
SetIntArrayRegion() jintArray jint
SetLongArrayRegion() jlong​​Array jlong
SetFloatArrayRegion() jfloatArray jfloat
SetDoubleArrayRegion() jdoubleArray jdouble

连锁:

JNIEnv接口函数表中的索引。

设置<PrimitiveType> ArrayRegion系列数组访问器例程

设置<PrimitiveType> ArrayRegion Routine 指数
SetBooleanArrayRegion() 207
SetByteArrayRegion() 208
SetCharArrayRegion() 209
SetShortArrayRegion() 210
SetIntArrayRegion() 211
SetLongArrayRegion() 212
SetFloatArrayRegion() 213
SetDoubleArrayRegion() 214

参数:

env :JNI接口指针。

array :一个Java数组。

start :起始指数。

len :要复制的元素数。

buf :源缓冲区。

抛出:

ArrayIndexOutOfBoundsException :如果该区域中的某个索引无效。

注意:从JDK / JRE 1.1开始,程序员可以使用Get/Release<primitivetype>ArrayElements函数来获取指向原始数组元素的指针。如果VM支持固定,则返回指向原始数据的指针; 否则,制作副本。

从JDK / JRE 1.3开始引入的新功能允许本机代码获取指向数组元素的直接指针,即使VM不支持固定。

GetPrimitiveArrayCritical,ReleasePrimitiveArrayCritical

void * GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy); 
void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode);

这两个函数的语义与现有Get/Release<primitivetype>ArrayElements函数非常相似。如果可能,VM返回指向基元数组的指针; 否则,制作副本。但是,如何使用这些功能存在重大限制。

调用之后GetPrimitiveArrayCritical,本机代码在调用之前不应该运行很长一段时间ReleasePrimitiveArrayCritical。我们必须将这对函数中的代码视为在“关键区域”中运行。在关键区域内,本机代码不能调用其他JNI函数或任何可能导致当前线程阻塞并等待另一个Java线程的系统调用。(例如,当前线程不能调用read另一个Java线程正在写入的流。)

这些限制使得本机代码更有可能获得阵列的未复制版本,即使VM不支持固定。例如,当本机代码持有指向通过其获得的数组的指针时,VM可以临时禁用垃圾收集GetPrimitiveArrayCritical

多对GetPrimtiveArrayCritical并且ReleasePrimitiveArrayCritical可以嵌套。例如:

  jint len = (*env)->GetArrayLength(env, arr1);
  jbyte *a1 = (*env)->GetPrimitiveArrayCritical(env, arr1, 0);
  jbyte *a2 = (*env)->GetPrimitiveArrayCritical(env, arr2, 0);
  /* We need to check in case the VM tried to make a copy. */
  if (a1 == NULL || a2 == NULL) {
    ... /* out of memory exception thrown */
  }
  memcpy(a1, a2, len);
  (*env)->ReleasePrimitiveArrayCritical(env, arr2, a2, 0);
  (*env)->ReleasePrimitiveArrayCritical(env, arr1, a1, 0);

请注意,GetPrimitiveArrayCritical如果VM在内部以不同格式表示数组,则可能仍会复制该数组。因此,我们需要针对NULL可能的内存不足情况检查其返回值。

LINKAGE(GetPrimitiveArrayCritical):

JNIEnv接口函数表中的链接索引222。

LINKAGE(ReleasePrimitiveArrayCritical):

JNIEnv接口函数表中的链接索引223。

以来:

JDK / JRE 1.2

注册本机方法

RegisterNatives

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

使用clazz参数指定的类注册本机方法。该methods参数指定JNINativeMethod包含本机方法的名称,签名和函数指针的结构数组。JNINativeMethod结构的namesignature字段是指向修改后的UTF-8字符串的指针。该nMethods参数指定数组中的本机方法数。的JNINativeMethod结构定义如下:

typedef struct {

    char *name;

    char *signature;

    void *fnPtr;

} JNINativeMethod;

名义上的函数指针必须具有以下签名:

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

连锁:

JNIEnv接口函数表中的索引215。

参数:

env :JNI接口指针。

clazz :Java类对象。

methods :类中的本机方法。

nMethods :类中的本机方法数。

返回值:

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

抛出:

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

UnregisterNatives

jint UnregisterNatives(JNIEnv *env, jclass clazz);

取消注册类的本机方法。该类返回到它与其本机方法函数链接或注册之前的状态。

此函数不应在普通本机代码中使用。相反,它为特殊程序提供了重新加载和重新链接本机库的方法。

连锁:

JNIEnv接口函数表中的索引216。

参数:

env :JNI接口指针。

clazz :Java类对象。

返回值:

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

监控操作

MonitorEnter

jint MonitorEnter(JNIEnv *env, jobject obj);

输入与引用的基础Java对象关联的监视器obj

输入与obj引用的对象关联的监视器。该obj参考绝不能NULL

每个Java对象都有一个与之关联的监视器。如果当前线程已拥有与之关联的监视器obj,则会增加监视器中的计数器,指示此线程进入监视器的次数。如果与之关联的监视器obj不属于任何线程,则当前线程将成为监视器的所有者,将此监视器的条目数设置为1.如果另一个线程已拥有与之关联的监视器obj,则当前线程将等待,直到监视器为释放,然后再次尝试获得所有权。

通过MonitorEnterJNI函数调用输入的监视器无法使用monitorexitJava虚拟机指令或同步方法返回退出。一个MonitorEnterJNI函数调用和monitorenterJava虚拟机指令可比赛进入与同一对象相关联的监视器。

为避免死锁,MonitorEnter必须使用MonitorExitJNI调用退出通过JNI函数调用输入的监视器,除非该DetachCurrentThread调用用于隐式释放JNI监视器。

连锁:

JNIEnv接口函数表中的索引217。

参数:

env :JNI接口指针。

obj :普通的Java对象或类对象。

返回值:

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

MonitorExit

jint MonitorExit(JNIEnv *env, jobject obj);

当前线程必须是与引用的基础Java对象关联的监视器的所有者obj。线程递减计数器,指示它进入此监视器的次数。如果计数器的值变为零,则当前线程释放监视器。

本机代码不得用于MonitorExit退出通过synchronized方法或monitorenterJava虚拟机指令输入的监视器。

连锁:

JNIEnv接口函数表中的索引218。

参数:

env :JNI接口指针。

obj :普通的Java对象或类对象。

返回值:

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

例外:

IllegalMonitorStateException :如果当前线程不拥有监视器。

NIO支持

与NIO相关的入口点允许本机代码访问java.nio 直接缓冲区。直接缓冲区的内容可能存在于普通垃圾收集堆之外的本机内存中。有关直接缓冲区的信息,

JDK / JRE 1.4中引入的三个新函数允许JNI代码创建,检查和操作直接缓冲区:

Java虚拟机的每个实现都必须支持这些功能,但并不是每个实现都需要支持对直接缓冲区的JNI访问。如果JVM不支持此类访问,则NewDirectByteBuffer和GetDirectBufferAddress函数必须始终返回NULL,并且GetDirectBufferCapacity函数必须始终返回-1。如果JVM 确实支持此类访问,则必须实现这三个函数以返回适当的值。

NewDirectByteBuffer

jobject NewDirectByteBuffer(JNIEnv * env,void * address,jlong​​ capacity);

分配并返回一个直接java.nio.ByteBuffer中参照所述存储器块起始于存储器地址的地址和延伸能力字节。

调用此函数并将生成的字节缓冲区对象返回到Java级代码的本机代码应确保缓冲区引用可供读取的内存的有效区域,并在适当时写入。尝试从Java代码访问无效的内存位置将返回任意值,没有可见效果,或导致抛出未指定的异常。

连锁:

JNIEnv接口函数表中的索引229。

参数:

env:JNIEnv接口指针

address:内存区域的起始地址(不能为NULL)

capacity:内存区域的大小(以字节为单位)(必须为正)

返回值:

返回对新实例化的java.nio.ByteBuffer对象的本地引用。如果发生异常,或者此虚拟机不支持对直接缓冲区的JNI访问,则返回NULL。

例外:

OutOfMemoryError:如果ByteBuffer对象的分配失败

以来:

JDK / JRE 1.4

GetDirectBufferAddress

void * GetDirectBufferAddress(JNIEnv * env,jobject buf);

获取并返回给定直接java.nio.Buffer引用的内存区域的起始地址。

此函数允许本机代码通过缓冲区对象访问Java代码可访问的相同内存区域。

连锁:

JNIEnv接口函数表中的索引230。

参数:

env:JNIEnv接口指针

buf:直接java.nio.Buffer对象(不能为NULL)

返回值:

返回缓冲区引用的内存区域的起始地址。如果内存区域未定义,如果给定对象不是直接java.nio.Buffer,或者此虚拟机不支持对直接缓冲区的JNI访问,则返回NULL。

以来:

JDK / JRE 1.4

GetDirectBufferCapacity

jlong​​ GetDirectBufferCapacity(JNIEnv * env,jobject buf);

获取并返回给定直接java.nio.Buffer引用的内存区域的容量。容量是内存区域包含的元素数。

连锁:

JNIEnv接口函数表中的索引231。

参数:

env:JNIEnv接口指针

buf:直接java.nio.Buffer对象(不能为NULL)

返回值:

返回与缓冲区关联的内存区域的容量。如果给定对象不是直接java.nio.Buffer,如果对象是未对齐的视图缓冲区且处理器体系结构不支持未对齐访问,或者此虚拟机不支持对直接缓冲区的JNI访问,则返回-1。

以来:

JDK / JRE 1.4

反思支持

如果程序员知道方法或字段的名称和类型,则可以使用JNI调用Java方法或访问Java字段。Java Core Reflection API允许程序员在运行时内省Java类。JNI在JNI中使用的字段和方法ID之间提供了一组转换函数,用于Java Core Reflection API中使用的字段和方法对象。

FromReflectedMethod

jmethodID FromReflectedMethod(JNIEnv *env, jobject method);

将a java.lang.reflect.Methodjava.lang.reflect.Constructorobject转换为方法ID。

连锁:

JNIEnv接口函数表中的索引7。

以来:

JDK / JRE 1.2

FromReflectedField

jfieldID FromReflectedField(JNIEnv *env, jobject field);

将a转换java.lang.reflect.Field为字段ID。

连锁:

JNIEnv接口函数表中的索引8。

以来:

JDK / JRE 1.2

ToReflectedMethod

jobject ToReflectedMethod(JNIEnv *env, jclass cls, 
jmethodID methodID, jboolean isStatic);

衍生自一种方法ID转换cls到一个java.lang.reflect.Methodjava.lang.reflect.Constructor对象。如果方法ID引用静态字段,则isStatic必须设置为JNI_TRUEJNI_FALSE否则。

OutOfMemoryError如果失败则抛出并返回0。

连锁:

JNIEnv接口函数表中的索引9。

以来:

JDK / JRE 1.2

ToReflectedField

jobject ToReflectedField(JNIEnv *env, jclass cls, 
jfieldID fieldID, jboolean isStatic);

将从派生的字段ID转换clsjava.lang.reflect.Field对象。isStatic必须设置为JNI_TRUEif fieldID引用静态字段,JNI_FALSE否则。

OutOfMemoryError如果失败则抛出并返回0。

连锁:

JNIEnv接口函数表中的索引12。

以来:

JDK / JRE 1.2

Java VM接口

GetJavaVM

jint GetJavaVM(JNIEnv *env, JavaVM **vm);

返回与当前线程关联的Java VM接口(在Invocation API中使用)。结果放在第二个参数指向的位置vm

连锁:

JNIEnv接口函数表中的索引219。

参数:

env :JNI接口指针。

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

返回值:

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

猜你喜欢

转载自blog.csdn.net/xinqingwuji/article/details/81205689