国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

JNI 常用API

2019-11-10 21:06:50
字體:
供稿:網(wǎng)友

利用JNIEnv自變量,程序員可訪問一系列函數(shù)。這些函數(shù)可劃分為下述類別:

■獲取版本信息

■進(jìn)行類和對(duì)象操作

■控制對(duì)java對(duì)象的全局和局部引用

■訪問實(shí)例字段和靜態(tài)字段

■調(diào)用實(shí)例方法和靜態(tài)方法

■執(zhí)行字串和數(shù)組操作

■產(chǎn)生和控制Java異常

 

獲取版本信息

jint GetVersion(JNIEnv *env);

 

獲取JNI函數(shù)版本信息,

返回值為jint類型,在c/c++中jint為32位數(shù),其中高16位是主版本號(hào),低16位是從版本號(hào)

In JDK/JRE 1.1, GetVersion() returns 0x00010001.

In JDK/JRE 1.2, GetVersion() returns 0x00010002.

In JDK/JRE 1.4, GetVersion() returns 0x00010004.

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

 

CLASSPATH 環(huán)境變量中搜索目錄和zip 文件中具有指定名稱的類。

 

參數(shù):

name: a fully-qualified class name  完全限定類 ,給出完整的類路徑,包名和類名使用“/”隔開

SINCE JDK/JRE 1.2:

 

產(chǎn)生和控制Java異常

 

jint Throw(JNIEnv *env, jthrowable obj);

 

拋出異常

 

參數(shù):jthrowable  是 java.lang.Throwable 包中對(duì)象.

 

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

 

通過消息構(gòu)造一個(gè)異常類,其中參數(shù)clazz 為 java.lang.Throwable包中的子類

 

jthrowable ExceptionOccurred(JNIEnv *env);

 

測(cè)試JVM是否有異常發(fā)生

 

SINCE JDK/JRE 1.2:

 

 

local reference 和 global reference。

 

Java 和JNI代碼之間函數(shù)調(diào)用時(shí),簡單類型,也就是內(nèi)置類型,比如 int, char 等是值傳遞(pass by value),而其它 Java 對(duì)象都是引用傳遞(pass by reference),這些對(duì)象引用由 JVM 傳給JNI代碼,每個(gè)都有其生命周期。

 

JNI 函數(shù)參數(shù)中 jobject 或者它的子類,其參數(shù)都是 local reference。Local reference 只在這個(gè) JNI函數(shù)中有效,JNI函數(shù)返回后,引用的對(duì)象就被釋放,它的生命周期就結(jié)束了。若要留著日后使用,則需根據(jù)這個(gè) local reference 創(chuàng)建 global reference。Global reference 不會(huì)被系統(tǒng)自動(dòng)釋放,它僅當(dāng)被程序明確調(diào)用 DeleteGlobalReference 時(shí)才被回收。(JNI多線程機(jī)制)

 

jobject NewGlobalRef(JNIEnv *env, jobject obj);

 

創(chuàng)建一個(gè)新的全局的引用,只能使用DeleteGlobalRef()函數(shù)銷毀這個(gè)全局引用

參數(shù):

Obj 一個(gè)本地引用或者全局引用

 

void DeleteGlobalRef(JNIEnv *env, jobject globalRef);

 

銷毀全局引用

參數(shù):

globalRef 使用NewGlobalRef()函數(shù)生成的全局引用

 

 void DeleteLocalRef(JNIEnv *env, jobject localRef);

 

銷毀本地的引用

 

注意:

JDK/JRE 1.1 提供了上面的 DeleteLocalRef 函數(shù),使程序員可以手動(dòng)刪除本地引用。例如,如果本機(jī)代碼遍歷可能很大的對(duì)象或數(shù)組,并使用每個(gè)迭代中的一個(gè)元素,好的做法是下一次迭代中創(chuàng)建一個(gè)新的本地引用之前刪除本地元素的引用。

JDK/JRE 1.2 和更高版本為本地引用生存周期管理提供了一套額外的函數(shù)。他們是下面列出的四種函數(shù)。

jint EnsureLocalCapacity(JNIEnv *env, jint capacity);

通知JVM 您將使用超過 16 個(gè)本地引用。這將允許 JVM 優(yōu)化對(duì)該本機(jī)代碼的本地引用的處理

jint PushLocalFrame(JNIEnv *env, jint capacity);

 

jobject PopLocalFrame(JNIEnv *env, jobject result);

先調(diào)用PushLocalFrame,然后創(chuàng)建局部引用,并對(duì)其進(jìn)行處理,最后調(diào)用PushLocalFrame釋放局部引用,這時(shí)Java虛擬機(jī)也可以對(duì)其指 向的對(duì)象進(jìn)行垃圾回收。可以用C語言的棧來理解這對(duì)JNI API,調(diào)用PushLocalFrame之后Native代碼創(chuàng)建的所有局部引用全部入棧,當(dāng)調(diào)用PopLocalFrame之后,入棧的局部引用除了 需要返回的局部引用(PushLocalFrame和PopLocalFrame這對(duì)函數(shù)可以返回一個(gè)局部引用給外部)之外,全部出棧,Java虛擬機(jī)這 時(shí)可以釋放他們指向的對(duì)象。具體的用法可以參考手冊(cè)。這兩個(gè)函數(shù)使JNI的局部引用由于和C語言的局部變量用法類似,所以強(qiáng)烈推薦使用

jobject NewLocalRef(JNIEnv *env, jobject ref);

1、Java虛擬機(jī)默認(rèn)為Native引用分配的局部引用數(shù)量是有限的,大部分的Java虛擬機(jī)實(shí)現(xiàn)默認(rèn)分配16個(gè)局部引用。當(dāng)然Java虛擬 機(jī)也提供API(PushLocalFrame,EnsureLocalCapacity)讓你申請(qǐng)更多的局部引用數(shù)量(Java虛擬機(jī)不保證你一定能申 請(qǐng)到)。有限的資源當(dāng)然要省著點(diǎn)用,否則將會(huì)被Java虛擬機(jī)無情拋棄(程序崩潰)。JNI編程中,實(shí)現(xiàn)Native代碼時(shí)強(qiáng)烈建議調(diào)用PushLocalFrame,EnsureLocalCapacity來確保Java虛擬機(jī)為你準(zhǔn)備好了局部變量空間。

2、如果你實(shí)現(xiàn)的Native函數(shù)是工具函數(shù),會(huì)被頻繁的調(diào)用。如果你在Native函數(shù)中沒有顯示刪除局部引用,那么每次調(diào)用該函數(shù)Java虛擬機(jī)都會(huì)創(chuàng)建一個(gè)新的局部引用,造成局部引用過多。尤其是該函數(shù)在Native代碼中被頻繁調(diào)用,代碼的控制權(quán)沒有交還給Java虛擬機(jī),所以Java虛擬機(jī)根本沒有機(jī)會(huì)釋放這些局部變量。退一步講,就算該函數(shù)直接返回給Java虛擬機(jī),也不能保證沒有問題,我們不能假設(shè)Native函數(shù)返回Java虛 擬機(jī)之后,Java虛擬機(jī)馬上就會(huì)回收Native函數(shù)中創(chuàng)建的局部引用,依賴于Java虛擬機(jī)實(shí)現(xiàn)。所以我們?cè)趯?shí)現(xiàn)Native函數(shù)時(shí)一定要記著刪除不 必要的局部引用,否則你的程序就有潛在的風(fēng)險(xiǎn),不知道什么時(shí)候就會(huì)爆發(fā)。

3、如果你Native函數(shù)根本就不返回。比如消息循環(huán)函數(shù)——死循環(huán)等待消息,處理消息。如果你不顯示刪除局部引用,很快將會(huì)造成Java虛擬機(jī)的局部引用內(nèi)存溢出。

Weak Global References

全局的弱引用是一種特殊的全局引用,與普通的全局引用不同全局的弱引用允許Java 對(duì)象進(jìn)行垃圾回收,當(dāng)垃圾收集器運(yùn)行時(shí),它將釋放對(duì)象,如果引用的對(duì)象只使用弱引用

jweak NewWeakGlobalRef(JNIEnv *env, jobject obj);

void DeleteWeakGlobalRef(JNIEnv *env, jweak obj);

SINCE JDK/JRE 1.2:

Object Operations

jobject AllocObject(JNIEnv *env, jclass clazz);

分配一個(gè)新的 Java 對(duì)象,而不調(diào)用任何對(duì)象的構(gòu)造函數(shù),僅僅是內(nèi)存創(chuàng)建

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

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

args: an array of arguments to the constructor.

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

args: a va_list of arguments to the constructor.

分配一個(gè)新的java對(duì)象,調(diào)用指定的構(gòu)造函數(shù),構(gòu)造函數(shù)使用methodID指定

jclass GetObjectClass(JNIEnv *env, jobject obj);

根據(jù)類的引用返回類的類型

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

測(cè)試類的引用類型,是返回JNI_TRUE 否則 返回JNI_FALSE

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

測(cè)試兩個(gè)引用類型是否指向同一個(gè)空間,是返回JNI_TRUE 否則 返回JNI_FALSE

 

accessing Fields of Objects

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

GetFieldID是得到java類中的參數(shù)ID,只能調(diào)用類中聲明為 public的屬性,jfieldID Get<type>Field andSet<type>Field 函數(shù)族使用

參數(shù):

Name 屬性在java類中的名字

Sig 類型簽名

Get<type>Field Routines

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

                                      

表 3-3    Get<type>Field Family of Accessor Routines

Get<type>Field Routine Name

Native Type

GetObjectField()

jobject

GetBooleanField()

jboolean

GetByteField()

jbyte

GetCharField()

jchar

GetShortField()

jshort

GetIntField()

jint

GetLongField()

jlong

GetFloatField()

jfloat

GetDoubleField()

jdouble

獲取java對(duì)象屬性的值

Set<type>Field Routines

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

表 3-4    Set<type>Field Family of Accessor Routines

Set<type>Field Routine Name

Native Type

SetObjectField()

jobject

SetBooleanField()

jboolean

SetByteField()

jbyte

SetCharField()

jchar

SetShortField()

jshort

SetIntField()

jint

SetLongField()

jlong

SetFloatField()

jfloat

SetDoubleField()

jdouble

設(shè)置java對(duì)象屬性的值

Calling Instance Methods

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

GetMethodID得到j(luò)ava類中方法的ID,它只能調(diào)用類中聲明為 public的方法,jmethodIDCall<type>Method函數(shù)族使用

參數(shù):

Name 方法在java類中的名字

Sig 類型簽名

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);

表 3-5    Instance Method Calling Routines

Call<type>Method Routine Name

Native Type

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

 

 

調(diào)用java方法通過jmethodID指定

如果想要調(diào)用一個(gè)對(duì)象的父類方法,而不是子類的這個(gè)方法的話,就可以使用NativeTypeCallNonvirtual<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);

表 3-6  CallNonvirtual<type>Method Routines

CallNonvirtual <type>Method Routine Name

Native Type

CallNonvirtualVoidMethod()

CallNonvirtualVoidMethodA()

CallNonvirtualVoidMethodV()

void

 

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

 

例:

package com.cn; public class Father {public void function(){System.out.PRintln("Father:function");}}

 

1.  package com.cn;

2.  public class Child extends Father {

3.  public void function() {

4.  System.out.println("Child:function");

5.  }

6.  }

 

package com.cn;public class TestNativeCall {public native void testCall ();public Father p = new Child();public static void main(String[] args) { System.loadLibrary("nativeCode");//Java類 中加載DLL,然后調(diào)用聲明的native方法TestNativeCall tst=new TestNativeCall ();tst.testCall ();}}

 

 

 

void Java_Com_Cn_ testCall (JNIEnv *env, jobject obj){ jfieldID id_p = env->GetFieldID (clazz_TestNative,"p","Lcom/cn/Father;");jobject p = env->GetObjectField(obj,id_p);//取得屬性 jclass clazz_Father = env->FindClass ("com/cn/Father");//找到Father類jmethodID id_Father_function = env->GetMethodID(clazz_Father,"function","()V");//獲取Father類里面方法的ID //調(diào)用方法,取得的是子類方法env->CallVoidMethod(p,id_Father_function); //調(diào)用父類方法env->CallNonvirtualVoidMethod(p,clazz_Father,id_Father_function);}

 

Accessing Static Fields

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

GetStaticFieldID得到j(luò)ava類中static 屬性ID,jfieldIDGetStatic<type>Field and SetStatic<type>Field函數(shù)族使用

參數(shù):

clazz java類對(duì)象

name 方法在java類中的名字

sig  類型簽名

 

GetStatic<type>Field Routines

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

表 3-7 

GetStatic<type>Field Family of Accessor Routines

GetStatic<type>Field Routine Name

Native Type

GetStaticObjectField ()

jobject

GetStaticBooleanField ()

jboolean

GetStaticByteField ()

jbyte

GetStaticCharField ()

jchar

GetStaticShortField ()

jshort

GetStaticIntField ()

jint

GetStaticLongField ()

jlong

GetStaticFloatField ()

jfloat

GetStaticDoubleField ()

jdouble

 

獲取java對(duì)象靜態(tài)屬性的值

 

SetStatic<type>Field Routines

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

 

表 3-8 

SetStatic<type>Field Family of Accessor Routines

SetStatic<type>Field Routine Name

Native Type

SetStaticObjectField ()

jobject

SetStaticBooleanField ()

jboolean

SetStaticByteField ()

jbyte

SetStaticCharField ()

jchar

SetStaticShortField ()

jshort

SetStaticIntField ()

jint

SetStaticLongField ()

jlong

SetStaticFloatField ()

jfloat

SetStaticDoubleField ()

jdouble

設(shè)置java對(duì)象靜態(tài)屬性的值

 

 

Calling Static Methods

GetStaticMethodID

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

 

GetStaticMethodID得到j(luò)ava類中static方法 ID,jmethodIDCallStatic<type>Method 函數(shù)使用

 

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);

 

 

表 3-9  CallStatic<type>Method Calling Routines

CallStatic <type>Method Routine Name

Native Type

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

 

 

String Operations

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

Array Operations

Registering Native Methods

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

 

typedef struct {

 

    char *name;

 

    char *signature;

 

    void *fnPtr;

 

} JNINativeMethod

 

Monitor Operations

jint MonitorEnter(JNIEnv *env, jobject obj);

jint MonitorExit(JNIEnv *env, jobject obj);

 

NIO Support

The NIO-related entry points allow native code to access java.nio direct buffers. The contents of a direct buffer can, potentially, reside in native memory outside of the ordinary garbage-collected heap. For information about direct buffers, please see New I/O APIs and the specification of the java.nio.ByteBuffer class.

Three new functions introduced in JDK/JRE 1.4 allow JNI code to create, examine, and manipulate direct buffers:

NewDirectByteBufferGetDirectBufferAddressGetDirectBufferCapacity

Reflection Support

 

Java VM Interface

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


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 西华县| 房山区| 黄石市| 长子县| 曲阜市| 临猗县| 扬州市| 潜江市| 桃园县| 泰兴市| 仙桃市| 湖南省| 会泽县| 吉隆县| 中西区| 南陵县| 武汉市| 阜新市| 滦南县| 怀仁县| 兰坪| 九龙城区| 娱乐| 水富县| 马公市| 齐河县| 巴马| 佳木斯市| 巴中市| 宁夏| 黑水县| 阿勒泰市| 临海市| 福鼎市| 华阴市| 格尔木市| 迭部县| 淅川县| 综艺| 淮安市| 会理县|