本章为JNI函数提供参考信息。其中列出了全部JNI函数,同时也给出了JNI函数表的准确布局。注意:“必须”一词用于约束JNI编程人员。例如,当说明某个JNI函数必须接收非空对象时,就应确保不要向该JNI函数传递NULL值。这时,JNI实现将无需在该JNI函数中执行NULL指针检查。
每个函数均可通过JNIEnv参数以固定偏移量进行访问。JNIEnv的类型是一个指针,指向存储全部JNI函数指针的结构。注意:前三项留作将来与COM兼容。此外,我们在函数表开头部分也留出来多个NULL项,从而可将将来与类有关的JNI操作添加到FindClass后面,而非函数表的末尾。注意,函数表可在所有JNI接口指针间共享。
const struct JNINativeInterface ... = {
NULL,
NULL,
NULL,
NULL,
GetVersion,
DefineClass,
FindClass,
NULL,
NULL,
NULL,
GetSuperclass,
IsAssignableFrom,
NULL,
Throw,
ThrowNew,
ExceptionOccurred,
ExceptionDescribe,
ExceptionClear,
FatalError,
NULL,
NULL,
NewGlobalRef,
DeleteGlobalRef,
DeleteLocalRef,
IsSameObject,
NULL,
NULL,
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,
};
GetVersion( )返回本地方法接口的版本。
jint GetVersion(JNIEnv *env);
参数 :
env为JNI接口指针。返回值:
高16位返回主版本号,低16位返回次版本号。
在JDK1.1 中,GetVersion()返回0x00010001。
DefineClass( )从原始类数据的缓冲区中加载类。
jclass DefineClass(JNIEnv *env, jobject loader, const jbyte *buf, jsize bufLen);
参数:
env:JNI 接口指针。
loader:分派给所定义的类的类加载器。
buf:包含.class文件数据的缓冲区。
bufLen:缓冲区长度。返回值:
返回Java类对象。如果出错则返回NULL。抛出的异常:
- ClassFormatError:如果类数据指定的类无效。
- ClassCircularityError:如果类或接口是自身的超类或超接口。
- OutOfMemoryError:如果系统内存不足。
FindClass( ) 该函数用于加载本地定义的类。它将搜索由CLASSPATH环境变量为具有指定名称的类所指定的目录和zip文件。
jclass FindClass(JNIEnv *env, const char *name);
参数:
env:JNI接口指针。
name:类全名(即包名后跟类名,之间由“/”分隔)。如果该名称以“[”(数组签名字符)打头,则返回一个数组类。返回值:
返回类对象全名。如果找不到该类,则返回NULL。抛出:
- ClassFormatError:如果类数据指定的类无效。
- ClassCircularityError:如果类或接口是自身的超类或超接口。
- NoClassDefFoundError:如果找不到所请求的类或接口的定义。
- OutOfMemoryError:如果系统内存不足。
GetSuperclass( ) 如果clazz代表类而非类object,则该函数返回由clazz所指定的类的超类。如果clazz指定类object或代表某个接口,则该函数返回NULL。
jclass GetSuperclass(JNIEnv *env, jclass clazz);
参数:
env:JNI接口指针。
clazz:Java类对象。返回值:
由clazz所代表的类的超类或NULL。
IsAssignableFrom ( ) 确定clazz1的对象是否可安全地强制转换为clazz2。
jboolean IsAssignableFrom(JNIEnv *env, jclass clazz1, jclass clazz2);
参数:
env:JNI接口指针。
clazz1:第一个类参数。
clazz2:第二个类参数。返回值:
下列某个情况为真时返回JNI_TRUE:
第一及第二个类参数引用同一个Java类。
第一个类是第二个类的子类。
第二个类是第一个类的某个接口。
Throw( ) 抛出java.lang.Throwable对象。
jint Throw(JNIEnv *env, jthrowable obj);
参数:
env:JNI接口指针。
obj:java.lang.Throwable对象。返回值:
成功时返回0,失败时返回负数。抛出:
java.lang.Throwable对象obj。
ThrowNew( )利用指定类的消息(由message指定)构造异常对象并抛出该异常。
jint ThrowNew(JNIEnv *env, jclass clazz, const char *message);
参数:
env:JNI接口指针。
clazz:java.lang.Throwable的子类。
message:用于构造java.lang.Throwable对象的消息。返回值:
成功时返回0,失败时返回负数。抛出:
新构造的java.lang.Throwable对象。
ExceptionOccurred( ) 确定是否某个异常正被抛出。在平台相关代码调用ExceptionClear()或Java代码处理该异常前,异常将始终保持抛出状态。
jthrowable ExceptionOccurred(JNIEnv *env);
参数:
env:JNI接口指针。返回值:
返回正被抛出的异常对象,如果当前无异常被抛出,则返回NULL。
ExceptionDescribe( ) 将异常及堆栈的回溯输出到系统错误报告信道(例如 stderr)。该例程可便利调试操作。
void ExceptionDescribe(JNIEnv *env);
参数:
env:JNI接口指针。
ExceptionClear( ) 清除当前抛出的任何异常。如果当前无异常,则此例程不产生任何效果。
void ExceptionClear(JNIEnv *env);
参数:
env:JNI接口指针。
FatalError( )抛出致命错误并且不希望虚拟机进行修复。该函数无返回值。
void FatalError(JNIEnv *env, const char *msg);
参数:
env:JNI接口指针。
msg:错误消息。
NewGlobalRef( ) 创建obj参数所引用对象的新全局引用。obj参数既可以是全局引用,也可以是局部引用。全局引用通过调用DeleteGlobalRef()来显式撤消。
jobject NewGlobalRef(JNIEnv *env, jobject obj);
参数:
env:JNI接口指针。
obj:全局或局部引用。返回值:
返回全局引用。如果系统内存不足则返回NULL。
DeleteGlobalRef( ) 删除globalRef所指向的全局引用。
void DeleteGlobalRef(JNIEnv *env, jobject globalRef);
参数:
env:JNI接口指针。
globalRef:全局引用。
DeleteLocalRef( ) 删除localRef所指向的局部引用。
void DeleteLocalRef(JNIEnv *env, jobject localRef);
参数:
env:JNI接口指针。
localRef:局部引用。
AllocObject( ) 分配新Java对象而不调用该对象的任何构造函数。返回该对象的引用。clazz参数务必不要引用数组类。
jobject AllocObject(JNIEnv *env, jclass clazz);
参数:
env:JNI接口指针。
clazz:Java类对象。返回值:
返回Java对象。如果无法构造该对象,则返回NULL。抛出:
InstantiationException:如果该类为一个接口或抽象类。
OutOfMemoryError:如果系统内存不足。
NewObject( ) NewObjectA( ) NewObjectV( ) 构造新Java对象。
jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...);
jobject NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args);
jobject NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
方法ID指示应调用的构造函数方法。该ID必须通过调用GetMethodID( )获得,且调用时的方法名必须为init,而返回类型必须为void(V)。clazz参数务必不要引用数组类。
NewObject( )
编程人员应将传递给构造函数的所有参数紧跟着放在methodID参数的后面。NewObject( )收到这些参数后,将把它们传给编程人员所要调用的Java方法。
NewObjectA( )
编程人员应将传递给构造函数的所有参数放在jvalues类型的数组args中,该数组紧跟着放在methodID参数的后面。NewObject()收到数组中的这些参数后,将把它们传给编程人员所要调用的Java方法。
NewObjectV( )
编程人员应将传递给构造函数的所有参数放在va_list类型的参数args中,该参数紧跟着放在methodID参数的后面。NewObject()收到这些参数后,将把它们传给编程人员所要调用的Java方法。
参数:
env:JNI接口指针。
clazz:Java类对象。
methodID:构造函数的方法ID。NewObject 的其它参数:
传给构造函数的参数。NewObjectA的其它参数:
args:传给构造函数的参数数组。NewObjectV的其它参数:
args:传给构造函数的参数va_list。返回值:
返回Java对象,如果无法构造该对象,则返回NULL。抛出:
InstantiationException:如果该类为接口或抽象类。
OutOfMemoryError:如果系统内存不足。构造函数抛出的任何异常。
GetObjectClass( ) 返回对象的类。
jclass GetObjectClass(JNIEnv *env, jobject obj);
参数:
env:JNI接口指针。
obj:Java对象(不能为NULL)。返回值:
返回Java类对象。
IsInstanceOf( ) 测试对象是否为某个类的实例。
jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz);
参数:
env:JNI接口指针。
obj:Java对象。
clazz:Java类对象。返回值:
如果可将obj强制转换为clazz,则返回JNI_TRUE。否则返回JNI_FALSE。NULL对象可强制转换为任何类。
IsSameObject( ) 测试两个引用是否引用同一Java对象。
jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2);
参数:
env:JNI接口指针。
ref1:Java对象。
ref2:Java对象。返回值:
如果ref1和ref2引用同一Java对象或均为NULL,则返回JNI_TRUE。否则返回JNI_FALSE。
GetFieldID( )
jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig);
返回类的实例(非静态)域的域ID。该域由其名称及签名指定。访问器函数的Get[type]Field及Set[type]Field系列使用域ID检索
对象域。GetFieldID( )将未初始化的类初始化。GetFieldID( )不能用于获取数组的长度域。应使GetArrayLength( )。
参数:
env:JNI接口指针。
clazz:Java类对象。
name: 0终结的UTF-8字符串中的域名。
sig:0终结的UTF-8字符串中的域签名。返回值:
域ID。如果操作失败,则返回NULL。抛出:
NoSuchFieldError:如果找不到指定的域。
ExceptionInInitializerError:如果由于异常而导致类初始化程序失败。
OutOfMemoryError:如果系统内存不足。
NativeType Get[type]Field(JNIEnv *env, jobject obj, jfieldID fieldID);
该访问器例程系列返回对象的实例(非静态)域的值。要访问的域由通过调用GetFieldID( )而得到的域ID指定。
参数:
env:JNI接口指针。
obj:Java对象(不能为 NULL)。
fieldID:有效的域ID。返回值:
域的内容。
下表说明了Get[type]Field例程名及结果类型。应将Get[type]Field中的type替换为域的Java类型(或使用表中的某个实际例程名),然后将NativeType替换为该例程对应的本地类型。
Get[type]Field例程名 | 本地类型 |
---|---|
GetObjectField( ) | jobject |
GetBooleanField( ) | jboolean |
GetByteField( ) | jbyte |
GetCharField( ) | jchar |
GetShortField( ) | jshort |
GetIntField( ) | jint |
GetLongField( ) | jlong |
GetFloatField( ) | jfloat |
GetDoubleField( ) | jdouble |
void Set[type]Field(JNIEnv *env, jobject obj, jfieldID fieldID, NativeType value);
该访问器例程系列设置对象的实例(非静态)域的值。要访问的域由通过调用SetFieldID( )而得到的域ID指定。
参数:
env:JNI接口指针。
obj:Java对象(不能为NULL)。
fieldID:有效的域ID。
value:域的新值。
下表说明了Set[type]Field例程名及结果类型。应将Set[type]Field中的type替换为域的Java类型(或使用表中的某个实际例程名),然后将NativeType替换为该例程对应的本地类型。
Set[type]Field例程名 | 本地类型 |
---|---|
Set[type]Field例程名 | 本地类型 |
SetObjectField( ) | jobject |
SetBooleanField( ) | jboolean |
SetByteField( ) | jbyte |
SetCharField( ) | jchar |
SetShortField( ) | jshort |
SetIntField( ) | jint |
SetLongField( ) | jlong |
SetFloatField( ) | jfloat |
SetDoubleField( ) | jdouble |
jmethodID GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig);
返回类或接口实例(非静态)方法的方法ID。方法可在某个clazz的超类中定义,也可从clazz继承。该方法由其名称和签名决定。GetMethodID( )可使未初始化的类初始化。要获得构造函数的方法ID,应将[init]作为方法名,同时将void (V)作为返回类型。
参数:
env:JNI接口指针。
clazz:Java类对象。
name:0终结的UTF-8字符串中的方法名。
sig:0终结的UTF-8字符串中的方法签名。返回值:
方法ID,如果找不到指定的方法,则为NULL。抛出:
NoSuchMethodError:如果找不到指定方法。
ExceptionInInitializerError:如果由于异常而导致类初始化程序失败。
OutOfMemoryError:如果系统内存不足。
NativeType Call[type]Method(JNIEnv *env, jobject obj, jmethodID methodID, ...);
NativeType Call[type]MethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args);
NativeType Call[type]MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
这三个操作的方法用于从本地方法调用Java实例方法。它们的差别仅在于向其所调用的方法传递参数时所用的机制。这三个操作将根据所指定的方法ID调用Java对象的实例(非静态)方法。参数methodID必须通过调用GetMethodID( )来获得。当这些函数用于调用私有方法和构造函数时,方法ID必须从obj的真实类派生而来,而不应从其某个超类派生。
参数:
env:JNI接口指针。
obj:Java对象。
methodID:方法ID。Call[type]Method例程的其它参数:
要传给Java方法的参数。Call[type]MethodA例程的其它参数:
args:参数数组。Call[type]MethodV例程的其它参数:
args:参数的va_list。返回值:
返回调用Java方法的结果。抛出:
执行Java方法时抛出的异常。
Call[type]Method例程
编程人员应将要传给方法的所有参数紧跟着放在methodID参数之后。Call[type]Method例程接受这些参数并将其传给编程人员所要调用的Java方法。
Call[type]MethodA例程
编程人员应将要传给方法的所有参数放在紧跟在methodID参数之后的jvalues类型数组args中。Call[type]MethodA routine接受这些数组中的参数并将其传给编程人员所要调用的Java方法。
Call[type]MethodV 例程
编程人员将方法的所有参数放在紧跟着在methodID参数之后的va_list类型参数变量中。Call[type]MethodV routine接受这些参数并将其传给编程人员所要调用的Java方法。
下表根据结果类型说明了各个方法调用例程。用户应将Call[type]Method中的type替换为所调用方法的Java类型(或使用表中的实际方法调用例程名),同时将NativeType替换为该例程相应的本地类型。
Call[type]Method例程名 | 本地类型 |
---|---|
CallVoidMethod( ) CallVoidMethodA( ) CallVoidMethodV( ) | void |
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 |
NativeType CallNonvirtual[type]Method(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
NativeType CallNonvirtual[type]MethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
NativeType CallNonvirtual[type]MethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args);
这些操作根据指定的类和方法ID调用某Java对象的实例(非静态)方法。参数methodID必须通过调用clazz类的GetMethodID( )获得。CallNonvirtual[type]Method和Call[type]Method例程系列并不相同。Call[type]Method例程根据对象的类调用方法,而CallNonvirtual[type]Method例程则根据获得方法ID的(由clazz参数指定)类调用方法。方法ID必须从对象的真实类或其某个超类获得。
参数:
env:JNI接口指针。
clazz:Java类。
obj: Java对象。
methodID:方法ID。CallNonvirtual[type]Method例程的其它参数:
要传给Java方法的参数。CallNonvirtual[type]MethodA例程的其它参数:
args:参数数组。CallNonvirtual[type]MethodV例程的其它参数:
args:参数的va_list。返回值:
调用Java方法的结果。抛出:
执行Java方法时所抛出的异常。
CallNonvirtual[type]Method例程
编程人员应将要传给方法的所有参数紧跟着放在methodID参数之后。CallNonvirtual[type]Method routine接受这些参数并将其传给编程人员所要调用的Java方法。
CallNonvirtual[type]MethodA例程
编程人员应将要传给方法的所有参数放在紧跟在methodID参数之后的jvalues类型数组args中。
CallNonvirtual[type]MethodA routine接受这些数组中的参数并将其传给编程人员所要调用的Java方法。
CallNonvirtual[type]MethodV例程
编程人员应将要传给方法的所有参数放在紧跟在methodID参数之后的va_list类型参数args中。CallNonvirtualMethodV routine接受这些参数并将其传给编程人员所要调用的Java方法。
下表根据结果类型说明了各个方法调用例程。用户应将CallNonvirtual[type]Method中的type替换为所调用方法的Java类型(或使用表中的实际方法调用例程名),同时将NativeType替换为该例程相应的本地类型。
CallNonvirtual[type]Method例程名 | 本地类型 |
---|---|
CallNonvirtualVoidMethod( ) CallNonvirtualVoidMethodA( ) CallNonvirtualVoidMethodV( ) | void |
CallNonvirtualObjectMethod( ) CallNonvirtualObjectMethodA( ) CallNonvirtualObjectMethodV( ) | jobject |
CallNonvirtualBooleanMethod( ) CallNonvirtualBooleanMethodA( ) CallNonvirtualBooleanMethodV( ) | jboolean |
CallNonvirtualByteMethod( ) CallNonvirtualByteMethodA( ) CallNonvirtualByteMethodV( ) | jbyte |
CallNonvirtualCharMethod( ) CallNonvirtualCharMethodA( ) CallNonvirtualCharMethodV( ) | jchar |
CallNonvirtualShortMethod( ) CallNonvirtualShortMethodA( ) CallNonvirtualShortMethodV( ) | |
CallNonvirtualIntMethod( ) CallNonvirtualIntMethodA( ) CallNonvirtualIntMethodV( ) | jint |
CallNonvirtualLongMethod( ) CallNonvirtualLongMethodA( ) CallNonvirtualLongMethodV( ) | jlong |
CallNonvirtualFloatMethod( ) CallNonvirtualFloatMethodA( ) CallNonvirtualFloatMethodV( ) | jfloat |
CallNonvirtualDoubleMethod( ) CallNonvirtualDoubleMethodA( ) CallNonvirtualDoubleMethodV( ) | jdouble |
jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig);
返回类的静态域的域ID。域由其名称和签名指定。GetStatic[type]Field和SetStatic[type]Field访问器函数系列使用域ID检索静态域。GetStaticFieldID()将未初始化的类初始化。
参数:
env:JNI接口指针。
clazz:Java类对象。
name: 0终结的UTF-8字符串中的静态域名。
sig:0终结的UTF-8字符串中的域签名。返回值:
域ID。如果找不到指定的静态域,则为NULL。
抛出:
NoSuchFieldError:如果找不到指定的静态域。
ExceptionInInitializerError:如果由于异常而导致类初始化程序失败。
OutOfMemoryError:如果系统内存不足。
NativeType GetStatic[type]Field(JNIEnv *env, jclass clazz, jfieldID fieldID);
该访问器例程系列返回对象的静态域的值。要访问的域由通过调用GetStaticFieldID()而得到的域ID指定。
参数:
env:JNI接口指针。
clazz:Java类对象。
fieldID:静态域ID。返回值:
静态域的内容。
下表说明了GetStatic[type]Field例程名及结果类型。应将GetStatic[type]Field中的type替换为域的Java类型(或使用表中的某个实际例程名),然后将NativeType替换为该例程对应的本地类型。
GetStatic[type]Field例程名 | 本地类型 |
---|---|
GetStaticObjectField( ) | jobject |
GetStaticBooleanField( ) | jboolean |
GetStaticByteField( ) | jbyte |
GetStaticCharField( ) | jchar |
GetStaticShortField( ) | jshort |
GetStaticIntField( ) | jint |
GetStaticLongField( ) | jlong |
GetStaticFloatField( ) | jfloat |
GetStaticDoubleField( ) | jdouble |
void SetStatic[type]Field(JNIEnv *env, jclass clazz, jfieldID fieldID, NativeType value);
该访问器例程系列设置对象的静态域的值。要访问的域由通过调用GetStaticFieldID()而得到的域ID指定。
参数:
env:JNI接口指针。
clazz:Java类对象。
fieldID:静态域ID。
value:域的新值。
下表说明了SetStatic[type]Field例程名及结果类型。应将SetStatic[type]Field中的type替换为域的Java类型(或使用表中的某个实际例程名),然后将NativeType替换为该例程对应的本地类型。
SetStatic[type]Field例程名 | 本地类型 |
---|---|
SetStaticObjectField( ) | jobject |
SetStaticBooleanField( ) | jboolean |
SetStaticByteField( ) | jbyte |
SetStaticCharField( ) | jchar |
SetStaticShortField( ) | jshort |
SetStaticIntField( ) | jint |
SetStaticLongField( ) | jlong |
SetStaticFloatField( ) | jfloat |
SetStaticDoubleField( ) | jdouble |
GetStaticMethodID( ) 返回类的静态方法的方法ID。方法由其名称和签名指定。GetStaticMethodID( )将未初始化的类初始化。
jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig);
参数:
env:JNI接口指针。
clazz:Java类对象。
name:0终结UTF-8字符串中的静态方法名。
sig:0终结UTF-8字符串中的方法签名。返回值:
方法ID,如果操作失败,则为NULL。抛出:
NoSuchMethodError:如果找不到指定的静态方法。
ExceptionInInitializerError:如果由于异常而导致类初始化程序失败。
OutOfMemoryError:如果系统内存不足。
NativeType CallStatic[type]Method(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派生,而不能从其超类派生。
参数:
env:JNI接口指针。
clazz:Java类对象。
methodID:静态方法ID。CallStatic[type]Method例程的其它参数:
要传给静态方法的参数。CallStatic[type]MethodA例程的其它参数:
args:参数数组。CallStatic[type]MethodV例程的其它参数:
args:参数的va_list。返回值:
返回调用静态Java方法的结果。抛出:
执行Java方法时抛出的异常。
CallStatic[type]Method例程
编程人员应将要传给方法的所有参数紧跟着放在methodID参数之后。CallStatic[type]Method routine接受这些参数并将其传给编程人员所要调用的Java方法。
CallStatic[type]MethodA例程
编程人员应将要传给方法的所有参数放在紧跟在methodID参数之后的jvalues类型数组args中。CallStaticMethodA routine接受这些数组中的参数并将其传给编程人员所要调用的Java方法。
CallStatic[type]MethodV例程
编程人员应将要传给方法的所有参数放在紧跟在methodID参数之后的va_list类型参数args中。CallStaticMethodV routine接受这些参数并将其传给编程人员所要调用的Java方法。
下表根据结果类型说明了各个方法调用例程。用户应将CallStatic[type]Method中的type替换为所调用方法的Java类型(或使用表中的实际方法调用例程名),同时将NativeType替换为该例程相应的本地类型。
CallStatic[type]Method例程名 | 本地类型 |
---|---|
CallStaticVoidMethod( ) CallStaticVoidMethodA( ) CallStaticVoidMethodV( ) | void |
CallStaticObjectMethod( ) CallStaticObjectMethodA( ) CallStaticObjectMethodV( ) | jobject |
CallStaticBooleanMethod( ) CallStaticBooleanMethodA( ) CallStaticBooleanMethodV( ) | jboolean |
CallStaticByteMethod( ) CallStaticByteMethodA( ) CallStaticByteMethodV( ) | jbyte |
CallStaticCharMethod( ) CallStaticCharMethodA( ) CallStaticCharMethodV( ) | jchar |
CallStaticShortMethod( ) CallStaticShortMethodA( ) CallStaticShortMethodV( ) | jshort |
CallStaticIntMethod( ) CallStaticIntMethodA( ) CallStaticIntMethodV( ) | jint |
CallStaticLongMethod( ) CallStaticLongMethodA( ) CallStaticLongMethodV( ) | jlong |
CallStaticFloatMethod( ) CallStaticFloatMethodA( ) CallStaticFloatMethodV( ) | jfloat |
CallStaticDoubleMethod( ) CallStaticDoubleMethodA( ) CallStaticDoubleMethodV( ) | jdouble |
NewString( ) 利用Unicode字符数组构造新的java.lang.String对象。
jstring NewString(JNIEnv *env, const jchar *unicodeChars, jsize len);
参数:
env:JNI接口指针。
unicodeChars:指向Unicode字符串的指针。
len:Unicode字符串的长度。返回值:
Java字符串对象。如果无法构造该字符串,则为NULL。抛出:
OutOfMemoryError:如果系统内存不足。
GetStringLength( ) 返回Java字符串的长度(Unicode字符数)。
jsize GetStringLength(JNIEnv *env, jstring string);
参数:
env:JNI接口指针。
string:Java字符串对象。返回值:
Java 字符串的长度。
GetStringChars( ) 返回指向字符串的Unicode字符数组的指针。该指针在调用ReleaseStringchars()前一直有效。如果isCopy非空,则在复制完成后将*isCopy设为JNI_TRUE。如果没有复制,则设为JNI_FALSE。
const jchar * GetStringChars(JNIEnv *env, jstring string, jboolean *isCopy);
参数:
env:JNI接口指针。
string:Java字符串对象。
isCopy:指向布尔值的指针。返回值:
指向Unicode字符串的指针,如果操作失败,则返回NULL。
ReleaseStringChars( ) 通知虚拟机平台相关代码无需再访问chars。参数chars是一个指针,可通过GetStringChars( )从string获得。
void ReleaseStringChars(JNIEnv *env, jstring string, const jchar *chars);
参数:
env:JNI接口指针。
string:Java字符串对象。
chars:指向Unicode字符串的指针。
NewStringUTF( ) 利用UTF-8字符数组构造新java.lang.String对象。
jstring NewStringUTF(JNIEnv *env, const char *bytes);
参数:
env:JNI接口指针。如果无法构造该字符串,则为NULL。
bytes:指向UTF-8字符串的指针。返回值:
Java字符串对象。如果无法构造该字符串,则为NULL。抛出:
OutOfMemoryError:如果系统内存不足。
GetStringUTFLength( ) 以字节为单位返回字符串的UTF-8长度。
jsize GetStringUTFLength(JNIEnv *env, jstring string);
参数:
env:JNI接口指针。
string:Java字符串对象。返回值:
返回字符串的UTF-8长度。
GetStringUTFChars( ) 返回指向字符串的UTF-8字符数组的指针。该数组在被ReleaseStringUTFChars( )释放前将一直有效。如果isCopy不是NULL,*isCopy在复制完成后即被设为JNI_TRUE。如果未复制,则设为JNI_FALSE。
const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy);
参数:
env:JNI接口指针。
string:Java字符串对象。
isCopy:指向布尔值的指针。返回值:
指向UTF-8字符串的指针。如果操作失败,则为NULL。
ReleaseStringUTFChars( ) 通知虚拟机平台相关代码无需再访问utf。utf参数是一个指针,可利用GetStringUTFChars( )从string获得。
void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf);
参数:
env:JNI接口指针。
string:Java字符串对象。
utf:指向UTF-8字符串的指针。
GetArrayLength( ) 返回数组中的元素数。
jsize GetArrayLength(JNIEnv *env, jarray array);
参数:
env:JNI接口指针。
array:Java数组对象。返回值:
数组的长度。
NewObjectArray( ) 构造新的数组,它将保存类elementClass中的对象。所有元素初始值均设为initialElement。
jarray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement);
参数:
env:JNI接口指针。
length:数组大小。
elementClass:数组元素类。
initialElement:初始值。返回值:
Java数组对象。如果无法构造数组,则为NULL。抛出:
OutOfMemoryError:如果系统内存不足。
GetObjectArrayElement( ) 返回Object数组的元素。
jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index);
参数:
env:JNI接口指针。
array:Java数组。
index:数组下标。返回值:
Java对象。抛出:
ArrayIndexOutOfBoundsException:如果index不是数组中的有效下标。
SetObjectArrayElement( ) 设置Object数组的元素。
void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value);
参数:
env:JNI接口指针。
array:Java数组。
index:数组下标。
value:新值。抛出:
ArrayIndexOutOfBoundsException:如果index不是数组中的有效下标。
ArrayStoreException:如果value的类不是数组元素类的子类。
New[PrimitiveType]Array( )例程
ArrayType NewArray(JNIEnv *env, jsize length);
用于构造新基本类型数组对象的一系列操作。
参数:
env:JNI接口指针。
length:数组长度。返回值:
Java数组。如果无法构造该数组,则为NULL。
下表说明了特定的基本类型数组构造函数。用户应把New[PrimitiveType]Array替换为
New[PrimitiveType]Array例程 | 数组类型 |
---|---|
NewBooleanArray( ) | jbooleanArray |
NewByteArray( ) | jbyteArray |
NewCharArray( ) | jcharArray |
NewShortArray( ) | jshortArray |
NewIntArray( ) | jintArray |
NewLongArray( ) | jlongArray |
NewFloatArray( ) | jfloatArray |
NewDoubleArray( ) | jdoubleArray |
Get[PrimitiveType]ArrayElements( )例程
jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index);
参数:
env:JNI接口指针。
array:Java数组。
index:数组下标。返回值:
Java对象。抛出:
ArrayIndexOutOfBoundsException:如果index不是数组中的有效下标。
SetObjectArrayElement( ) 设置Object数组的元素。
void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value);
参数:
env:JNI接口指针。
array:Java数组。
index:数组下标。
value:新值。抛出:
ArrayIndexOutOfBoundsException:如果index不是数组中的有效下标。
ArrayStoreException:如果value的类不是数组元素类的子类。
New[PrimitiveType]Array( )例程
ArrayType NewArray(JNIEnv *env, jsize length);
用于构造新基本类型数组对象的一系列操作。
参数:
env:JNI接口指针。
length:数组长度。返回值:
Java数组。如果无法构造该数组,则为NULL。
下表说明了特定的基本类型数组构造函数。用户应把New[PrimitiveType]Array替换为某个实际的基本类型数组构造函数例程名(见下表),然后将ArrayType替换为该例程相应的数组类型。
|New[PrimitiveType]Array例程 |数组类型
NewBooleanArray( ) | jbooleanArray |
---|---|
NewByteArray( ) | jbyteArray |
NewCharArray( ) | jcharArray |
NewShortArray( ) | jshortArray |
NewIntArray( ) | jintArray |
NewLongArray( ) | jlongArray |
NewFloatArray( ) | jfloatArray |
NewDoubleArray( ) | jdoubleArray |
Get[PrimitiveType]ArrayElements( )例程
NativeType *GetArrayElements(JNIEnv *env, ArrayType array, jboolean *isCopy);
一组返回基本类型数组体的函数。
结果在调用相应的Release[PrimitiveType]ArrayElements( )函数前将一直有效。由于返回的数组可能是Java数组的副本,因此对返回数组的更改不必在基本类型数组中反映出来,直到调用了Release[PrimitiveType]ArrayElements()。
如果isCopy不是NULL,*isCopy在复制完成后即被设为JNI_TRUE。如果未复制,则设为JNI_FALSE。
参数:
env:JNI接口指针。
array:Java字符串对象。
isCopy:指向布尔值的指针。返回值:
返回指向数组元素的指针,如果操作失败,则为NULL。
下表说明了特定的基本类型数组元素访问器。应进行下列替换;
将Get[PrimitiveType]ArrayElements替换为表中某个实际的基本类型元素访问器例程名。
将ArrayType替换为对应的数组类型。
将NativeType替换为该例程对应的本地类型。
不管布尔数组在Java虚拟机中如何表示,GetBooleanArrayElements( )将始终返回一个jbooleans类型的指针,其中每一字节代表一个元素(开包表示)。内存中将确保所有其它类型的数组为连续的。
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 |
Release[PrimitiveType]ArrayElements( )例程
void ReleaseArrayElements(JNIEnv *env, ArrayType array, NativeType *elems, jint mode);
通知虚拟机平台相关代码无需再访问elems的一组函数。
elems参数是一个通过使用对应的Get[PrimitiveType]ArrayElements()函数由array导出的指针。必要时,该函数将把对elems的修改复制回基本类型数组。mode参数将提供有关如何释放数组缓冲区的信息。如果elems不是array中数组元素的副本,mode将无效。否则,mode将具有下表所述的功能:
基本类型数组释放模 | 动作 |
---|---|
0 | 复制回内容并释放elems缓冲区 |
JNI_COMMIT | 复制回内容但不释放elems缓冲区 |
JNI_ABORT | 释放缓冲区但不复制回变化 |
多数情况下,编程人员将把“0”传给mode参数以确保固定的数组和复制的数组保持一致。其它选项可以使编程人员进一步控制内存管理,但使用时务必慎重。
参数:
env:JNI接口指针。
array:Java数组对象。
elems:指向数组元素的指针。
mode:释放模式。
下表说明了构成基本类型数组撤消程序系列的特定例程。应进行如下替换;
- 将Release[PrimitiveType]ArrayElements 替换为下表中的某个实际基本类型数组撤消程序例程名。
- 将ArrayType替换为对应的数组类型。
- 将NativeType替换为该例程对应的本地类型。
ReleaseArrayElements例程 数组类型 本地类型 ReleaseBooleanArrayElements( ) jbooleanArray jboolean ReleaseByteArrayElements( ) jbyteArray jbyte ReleaseCharArrayElements( ) jcharArray jchar ReleaseShortArrayElements( ) jshortArray jshort ReleaseIntArrayElements( ) jintArray jint ReleaseLongArrayElements( ) jlongArray jlong ReleaseFloatArrayElements( ) jfloatArray jfloat ReleaseDoubleArrayElements( ) jdoubleArray jdouble
Get[PrimitiveType]ArrayRegion例程
void GetArrayRegion(JNIEnv *env, ArrayType array, jsize start, jsize len, NativeType *buf);
将基本类型数组某一区域复制到缓冲区中的一组函数。
参数:
env:JNI接口指针。
array:Java指针。
start:起始下标。
len:要复制的元素数。
buf:目的缓冲区。抛出:
ArrayIndexOutOfBoundsException:如果区域中的某个下标无效。
下表说明了特定的基本类型数组元素访问器。应进行如下替换:
- 将Get[PrimitiveType]ArrayRegion替换为表中的某个实际基本类型元素访问器例程名。
- 将 ArrayType 替换为对应的数组类型。
- 将 NativeType 替换为该例程对应的本地类型。
Get[PrimitiveType]ArrayRegion例程 数组类型 本地类型 GetBooleanArrayRegion( ) jbooleanArray jboolean GetByteArrayRegion( ) jbyteArray jbyte GetCharArrayRegion( ) jcharArray jchar GetShortArrayRegion( ) jshortArray jshort GetIntArrayRegion( ) jintArray jint GetLongArrayRegion( ) jlongArray jlong GetFloatArrayRegion( ) jfloatArray jfloat GetDoubleArrayRegion( ) jdoubleArray jdouble
Set[PrimitiveType]ArrayRegion例程
void SetArrayRegion(JNIEnv *env, ArrayType array, jsize start, jsize len, NativeType *buf);
将基本类型数组的某一区域从缓冲区中复制回来的一组函数。
参数:
env:JNI接口指针。
array: Java数组。
start:起始下标。
len:要复制的元素数。
buf:源缓冲区。抛出:
ArrayIndexOutOfBoundsException:如果区域中的某个下标无效。
下表说明了特定的基本类型数组元素访问器。应进行如下替换:
- 将Set[PrimitiveType]ArrayRegion替换为表中的实际基本类型元素访问器例程名。
- 将ArrayType替换为对应的数组类型。
- 将NativeType替换为该例程对应的本地类型。
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
RegisterNatives( )
jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods);
向clazz参数指定的类注册本地方法。methods参数将指定JNINativeMethod结构的数组,其中包含本地方法的名称、签名和函数指针。nMethods参数将指定数组中的本地方法数。
参数:
env:JNI接口指针。
clazz:Java类对象。
methods:类中的本地方法。
nMethods:类中的本地方法数。返回值:
成功时返回 “0”;失败时返回负数。抛出:
NoSuchMethodError:如果找不到指定的方法或方法不是本地方法。
JNINativeMethod 结构定义如下所示:
typedef struct {
char *name;
char *signature;
void *fnPtr;
} JNINativeMethod;
函数指针通常必须有下列签名:
ReturnType (*fnPtr)(JNIEnv *env, jobject objectOrClass, ...);
UnregisterNatives( )
jint UnregisterNatives(JNIEnv *env, jclass clazz);
取消注册类的本地方法。类将返回到链接或注册了本地方法函数前的状态。该函数不应在常规平台相关代码中使用。相反,它可以为某些程序提供一种重新加载和重新链接本地库的途径。
参数:
env:JNI接口指针。
clazz:Java类对象。返回值:
成功时返回“0”;失败时返回负数。
MonitorEnter( )
jint MonitorEnter(JNIEnv *env, jobject obj);
进入与obj所引用的基本Java对象相关联的监视程序。每个Java对象都有一个相关联的监视程序。如果当前线程已经拥有与obj相关联的监视程序,它将使指示该线程进入监视程序次数的监视程序计数器增 1。如果与 obj 相关联的监视程序并非由某个线程所拥有,则当前线程将变为该监视程序的所有者,同时将该监视程序的计数器设置为 1。如果另一个线程已拥有与 obj 关联的监视程序,则在监视程序被释放前当前线程将处于等待状态。监视程序被释放后,当前线程将尝试重新获得所有权。
参数:
env:JNI接口指针。
obj:常规Java对象或类对象。返回值:
成功时返回“0”;失败时返回负数。
MonitorExit( )
jint MonitorExit(JNIEnv *env, jobject obj);
当前线程必须是与obj所引用的基本Java对象相关联的监视程序的所有者。线程将使指示进入监视程序次数的计数器减 1。如果计数器的值变为 0,当前线程释放监视程序。
参数:
env:JNI接口指针。
obj:常规Java对象或类对象。返回值:
成功时返回“0”;失败时返回负数。
GetJavaVM( )
jint GetJavaVM(JNIEnv *env, JavaVM **vm);
返回与当前线程相关联的Java虚拟机接口(用于调用API中)。结果将放在第二个参数vm所指向的位置。
参数:
env:JNI接口指针。
vm:指向放置结果的位置的指针。返回值:
成功时返回“0”;失败时返回负数。
调用API允许软件厂商将Java虚拟机加载到任意的本地程序中。厂商可以交付支持Java的应用程序,而不必链接Java虚拟机源代码。本章首先概述了调用API。然后是所有调用API函数的引用页。若要增强Java虚拟机的嵌入性,可以用几种方式来扩展JDK 1.1.2中的调用API。
以下代码示例说明了如何使用调用API中的函数。在本例中,C++代码创建Java虚拟机并且调用名为Main.test的静态方法。为清楚起见,我们略去了错误检查。
#include <jni.h>
/* 其中定义了所有的事项 */
JavaVM *jvm;
/* 表示 Java 虚拟机*/
JNIEnv *env;
/* 指向本地方法接口的指针 */
JDK1_1InitArgs vm_args; /* JDK 1.1 虚拟机初始化参数 */
vm_args.version = 0x00010001; /* 1.1.2 中新增的:虚拟机版本 */
/* 获得缺省的初始化参数并且设置类路径 */
JNI_GetDefaultJavaVMInitArgs(&vm_args);
vm_args.classpath = ...;
/* 加载并初始化 Java 虚拟机,返回env中的JNI 接口指针 */
JNI_CreateJavaVM(&jvm, &env, &vm_args);
/* 用 JNI 调用 Main.test 方法 */
jclass cls = env->FindClass("Main");
jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V");
env->CallStaticVoidMethod(cls, mid, 100);
/* 结束。*/
jvm->DestroyJavaVM();
本例使用了API中的三个函数。调用API允许本地应用程序用JNI接口指针来访问虚拟机特性。其设计类似于Netscape的JRI嵌入式接口。
JNI_CreateJavaVM()函数加载并初始化Java虚拟机,然后将指针返回到JNI接口指针。调用JNI_CreateJavaVM()的线程被看作主线程。
主线程不能自己断开与虚拟机的连接。而是必须调用DestroyJavaVM( )来卸载整个虚拟机。
虚拟机等到主线程成为唯一的用户线程时才真正地卸载。用户线程包括Java线程和附加的本地线程。之所以存在这种限制是因为Java线程或附加的本地线程可能正占用着系统资源,例如锁,窗口等。虚拟机不能自动释放这些资源。卸载虚拟机时,通过将主线程限制为唯一的运行线程,使释放任意线程所占用系统资源的负担落到程序员身上。
不同的Java虚拟机实现可能会需要不同的初始化参数。很难提出适合于所有现有和将来的Java虚拟机的标准初始化结构。作为一种折衷方式,我们保留了第一个域(version)来识别初始化结构的内容。嵌入到JDK 1.1.2中的本地应用程序必须将版本域设置为0x00010001。尽管其它实现可能会忽略某些由JDK所支持的初始化参数,我们仍然鼓励虚拟机实现使用与JDK一样的初始化结构。0x80000000到0xFFFFFFFF之间的版本号需保留,并且不为任何虚拟机实现所识别。
以下代码显示了初始化JDK 1.1.2中的Java虚拟机所用的结构。
typedef struct JavaVMInitArgs {
/* 前两个域在 JDK 1.1 中保留,并在 JDK 1.1.2 中正式引入。*/
/* Java 虚拟机版本 */
jint version;
/* 系统属性。*/
char **properties;
/* 是否检查 Java 源文件与已编译的类文件之间的新旧关系。*/
jint checkSource;
/* Java 创建的线程的最大本地堆栈大小。*/
jint nativeStackSize;
/* 最大 Java 堆栈大小。*/
jint javaStackSize;
/* 初始堆大小。*/
jint minHeapSize;
/* 最大堆大小。*/
jint maxHeapSize;
/* 控制是否校验 Java 字节码:0 无,1 远程加载的代码,2 所有代码。*/
jint verifyMode;
/* 类加载的本地目录路径。*/
const char *classpath;
/* 重定向所有虚拟机消息的函数的钩子。*/
jint (*vfprintf)(FILE *fp, const char *format, va_list args);
/* 虚拟机退出钩子。*/
void (*exit)(jint code);
/* 虚拟机放弃钩子。*/
void (*abort)();
/* 是否启用类 GC。*/
jint enableClassGC;
/* GC 消息是否出现。*/
jint enableVerboseGC;
/* 是否允许异步 GC。*/
jint disableAsyncGC;
/* 三个保留的域。*/
jint reserved0;
jint reserved1;
jint reserved2;
} JDK1_1InitArgs;
在JDK 1.1.2中,初始化结构提供了钩子,这样在虚拟机终止时,本地应用程序可以重定向虚拟机消息并获得控制权。当本地线程与JDK 1.1.2中的Java虚拟机连接时,以下结构将作为参数进行传递。实际上,本地线程与JDK 1.1.2连接时不需要任何参数。JDK1_1AttachArgs 结构仅由C编译器的填充槽组成,而C编译器不允许空结构。
typedef struct JDK1_1AttachArgs {
/*
* JDK 1.1 不需要任何参数来附加本地线程。此处填充的作用是为了满足不允许空结构的C编译器的要求。
*/
void *__padding;
} JDK1_1AttachArgs;
JavaVM类型是指向调用API函数表的指针。以下代码示例显示了这种函数表。
typedef const struct JNIInvokeInterface *JavaVM;
const struct JNIInvokeInterface ... = {
NULL,
NULL,
NULL,
DestroyJavaVM,
AttachCurrentThread,
DetachCurrentThread,
};
注意,JNI_GetDefaultJavaVMInitArgs( )、JNI_GetCreatedJavaVMs( )和JNI_CreateJavaVM( ) 这三个调用API函数不是JavaVM函数表的一部分。不必先有JavaVM结构,就可以使用这些函数。
JNI_GetDefaultJavaVMInitArgs( )
jint JNI_GetDefaultJavaVMInitArgs(void *vm_args);
返回Java虚拟机的缺省配置。在调用该函数之前,平台相关代码必须将vm_args->version 域设置为它所期望虚拟机支持的JNI版本。在JDK 1.1.2中,必须将vm_args->version设置为0x00010001。(JDK 1.1不要求平台相关代码设置版本域。为了向后兼容性,如果没有设置版本域,则JDK 1.1.2假定所请求的版本为0x00010001。JDK的未来版本将要求把版本域设置为适当的值。)该函数返回后,将把vm_args->version设置为虚拟机支持的实际JNI版本。
参数:
vm_args:指向VM-specific initialization(特定于虚拟机的初始化)结构的指针,缺省参数填入该结构。返回值:
如果所请求的版本得到支持,则返回“0”;如果所请求的版本未得到支持,则返回负数。
JNI_GetCreatedJavaVMs( )
jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs);
返回所有已创建的Java虚拟机。将指向虚拟机的指针依据其创建顺序写入vmBuf缓冲区。最多写入bufLen项。在*nVMs中返回所创建虚拟机的总数。JDK 1.1不支持在单个进程中创建多个虚拟机。
参数:
vmBuf:指向将放置虚拟机结构的缓冲区的指针。
bufLen:缓冲区的长度。
nVMs:指向整数的指针。返回值:
成功时返回“0”;失败则返回负数。
JNI_CreateJavaVM( )
jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args);
加载并初始化Java虚拟机。当前线程成为主线程。将env参数设置为主线程的JNI接口指针。JDK 1.1.2不支持在单个进程中创建多个虚拟机。必须将vm_args中的版本域设置为0x00010001。
参数:
p_vm:指向位置(其中放置所得到的虚拟机结构)的指针。
p_env:指向位置(其中放置主线程的 JNI 接口指针)的指针。
vm_args: Java 虚拟机初始化参数。返回值:
成功时返回“0”;失败则返回负数。
DestroyJavaVM( )
jint DestroyJavaVM(JavaVM *vm);
卸载Java虚拟机并回收资源。只有主线程能够卸载虚拟机。调用DestroyJavaVM( ) 时,主线程必须是唯一的剩余用户线程。
参数:
vm:将销毁的Java虚拟机。返回值:
成功时返回“0”;失败则返回负数。JDK 1.1.2 不支持卸载虚拟机。
AttachCurrentThread( )
jint AttachCurrentThread(JavaVM *vm, JNIEnv **p_env, void *thr_args);
将当前线程连接到Java虚拟机。在JNIEnv参数中返回JNI接口指针。试图连接已经连接的线程将不执行任何操作。本地线程不能同时连接到两个Java虚拟机上。
参数:
vm:当前线程所要连接到的虚拟机。
p_env:指向位置(其中放置当前线程的 JNI 接口指针)的指针。
thr_args:特定于虚拟机的线程连接参数。返回值:
成功时返回“0”;失败则返回负数。
DetachCurrentThread( )
jint DetachCurrentThread(JavaVM *vm);
断开当前线程与Java虚拟机之间的连接。释放该线程占用的所有Java监视程序。通知所有等待该线程终止的Java线程。主线程(即创建Java虚拟机的线程)不能断开与虚拟机之间的连接。作为替代,主线程必须调用JNI_DestroyJavaVM( )来卸载整个虚拟机。
参数:
vm:当前线程将断开连接的虚拟机。返回值:
成功时返回“0”;失败则返回负数。
CreateFile( )
函数原型
HANDLE CreateFile( LPCTSTR lpfileName, DWORD deDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes DWORD dwCreationDesposition, DWORD dwFlagsAndAtrributes, HANDLE hTemplateFile );
函数说明
该函数创建、打开或截断一个文件,并返回一个能够被用来存取该文件的句柄。此句柄允许读书据、写数据以及移动文件的指针。CreateFile函数既可以做为一个宽自负函数使用,也可以作为一个ANSI函数来用。参数说明
lpFileName:指向文件字符串的指针。
dwDesireAccess:制定文件的存取模式,可以取下列值:
- 0:制定可以查询对象。
- GENERIC_READ:指定可以从文件中度去数据。
- GENERIC_WRITE:指定可以向文件中写数据。
dwShareMode:指定文件的共享模式,可以取下列值:
- 0:不共享。
- FILE_SHARE_DELETE:在 Windows NT 系统中,只有为了删除文件而进行的打开操作才会成功。
- FILE_SHARE_READ:只有为了从文件中度去数据而进行的打开操作才会成功。
- FILE_SHARE_WRITE:只有为了向文件中写数据而进行的打开操作才会成功。
lpSecurityAttributes :指定文件的安全属性。
dwCreationDisopsition:指定创建文件的方式,可以取以下值:
- CREATE_NEW:创建新文件,如果文件已存在,则函数失败。
- CREATE_ALWAYS:创建爱内心文件,如果文件已存在,则函数将覆盖并清除旧文件。
- OPEN_EXISTING:打开文件,如果文件不存在,函数将失败。
- OPEN_ALWAYS:打开文件,如果文件不存在,则函数将创建一个新文件。
- TRUNCATE_EXISTING:打开外呢间,如果文件存在,函数将文件的大小设为零,如果文件不存在,函数将失败返回。
dwFlagsAndAtrributes :指定新建文件的属性和标志,它可以取以下值:
- FILE_ATTRIBUTE_ARCHIVE:归档属性。
- FILE_ATTRIBUTE_HIDDEN:隐藏属性。
- FILE_ATTRIBUTE_NORMAL:正常属性。
- FILE_ATTRIBUTE_READONLY:只读属性。
- FILE_ATTRIBUTE_READONLY:只读属性。
- FILE_ATTRIBUTE_TEMPORARY:临时存储文件,系统总是将临时文件的所有数据读入内存中,以加速对该文件的访问速度。用户应该尽快删除不再使用的临时文件。
- FILE_FLAG_OVERLAPPED:用户可以通过一个 OVERLAPPED 结构变量来保存和设置文件读写指针,从而可以完成重叠式的读和写。一般用于数量比较大的读些操作。
hTemplateFile :指向一个具有GENERIC_READ属性的文件的句柄,该文件为要创建的文件提供文件属性和文件扩展属性。
注意事项
函数成功将返回指定文件的句柄,否则返回NULL。
至此整个JNI完全手册引用结束。日后开发过程中该手册相当于一本字典,可以用来查阅。
本文内容主要参考http://blog.csdn.net/yanbober/article/details/45310365,感谢博主的辛劳……