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

首頁 > 學院 > 開發設計 > 正文

JNI 常用API

2019-11-11 00:32:40
字體:
來源:轉載
供稿:網友

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

■獲取版本信息

■進行類和對象操作

■控制對java對象的全局和局部引用

■訪問實例字段和靜態字段

■調用實例方法和靜態方法

■執行字串和數組操作

■產生和控制Java異常

 

獲取版本信息

jint GetVersion(JNIEnv *env);

 

獲取JNI函數版本信息,

返回值為jint類型,在c/c++中jint為32位數,其中高16位是主版本號,低16位是從版本號

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 環境變量中搜索目錄和zip 文件中具有指定名稱的類。

 

參數:

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

SINCE JDK/JRE 1.2:

 

產生和控制Java異常

 

jint Throw(JNIEnv *env, jthrowable obj);

 

拋出異常

 

參數:jthrowable  是 java.lang.Throwable 包中對象.

 

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

 

通過消息構造一個異常類,其中參數clazz 為 java.lang.Throwable包中的子類

 

jthrowable ExceptionOccurred(JNIEnv *env);

 

測試JVM是否有異常發生

 

SINCE JDK/JRE 1.2:

 

 

local reference 和 global reference。

 

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

 

JNI 函數參數中 jobject 或者它的子類,其參數都是 local reference。Local reference 只在這個 JNI函數中有效,JNI函數返回后,引用的對象就被釋放,它的生命周期就結束了。若要留著日后使用,則需根據這個 local reference 創建 global reference。Global reference 不會被系統自動釋放,它僅當被程序明確調用 DeleteGlobalReference 時才被回收。(JNI多線程機制)

 

jobject NewGlobalRef(JNIEnv *env, jobject obj);

 

創建一個新的全局的引用,只能使用DeleteGlobalRef()函數銷毀這個全局引用

參數:

Obj 一個本地引用或者全局引用

 

void DeleteGlobalRef(JNIEnv *env, jobject globalRef);

 

銷毀全局引用

參數:

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

 

 void DeleteLocalRef(JNIEnv *env, jobject localRef);

 

銷毀本地的引用

 

注意:

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

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

jint EnsureLocalCapacity(JNIEnv *env, jint capacity);

通知JVM 您將使用超過 16 個本地引用。這將允許 JVM 優化對該本機代碼的本地引用的處理

jint PushLocalFrame(JNIEnv *env, jint capacity);

 

jobject PopLocalFrame(JNIEnv *env, jobject result);

先調用PushLocalFrame,然后創建局部引用,并對其進行處理,最后調用PushLocalFrame釋放局部引用,這時Java虛擬機也可以對其指 向的對象進行垃圾回收??梢杂肅語言的棧來理解這對JNI API,調用PushLocalFrame之后Native代碼創建的所有局部引用全部入棧,當調用PopLocalFrame之后,入棧的局部引用除了 需要返回的局部引用(PushLocalFrame和PopLocalFrame這對函數可以返回一個局部引用給外部)之外,全部出棧,Java虛擬機這 時可以釋放他們指向的對象。具體的用法可以參考手冊。這兩個函數使JNI的局部引用由于和C語言的局部變量用法類似,所以強烈推薦使用

jobject NewLocalRef(JNIEnv *env, jobject ref);

1、Java虛擬機默認為Native引用分配的局部引用數量是有限的,大部分的Java虛擬機實現默認分配16個局部引用。當然Java虛擬 機也提供API(PushLocalFrame,EnsureLocalCapacity)讓你申請更多的局部引用數量(Java虛擬機不保證你一定能申 請到)。有限的資源當然要省著點用,否則將會被Java虛擬機無情拋棄(程序崩潰)。JNI編程中,實現Native代碼時強烈建議調用PushLocalFrame,EnsureLocalCapacity來確保Java虛擬機為你準備好了局部變量空間。

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

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

Weak Global References

全局的弱引用是一種特殊的全局引用,與普通的全局引用不同全局的弱引用允許Java 對象進行垃圾回收,當垃圾收集器運行時,它將釋放對象,如果引用的對象只使用弱引用

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

分配一個新的 Java 對象,而不調用任何對象的構造函數,僅僅是內存創建

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.

分配一個新的java對象,調用指定的構造函數,構造函數使用methodID指定

jclass GetObjectClass(JNIEnv *env, jobject obj);

根據類的引用返回類的類型

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

測試類的引用類型,是返回JNI_TRUE 否則 返回JNI_FALSE

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

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

 

accessing Fields of Objects

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

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

參數:

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對象屬性的值

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

設置java對象屬性的值

Calling Instance Methods

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

GetMethodID得到java類中方法的ID,它只能調用類中聲明為 public的方法,jmethodIDCall<type>Method函數族使用

參數:

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

 

 

調用java方法通過jmethodID指定

如果想要調用一個對象的父類方法,而不是子類的這個方法的話,就可以使用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,然后調用聲明的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 //調用方法,取得的是子類方法env->CallVoidMethod(p,id_Father_function); //調用父類方法env->CallNonvirtualVoidMethod(p,clazz_Father,id_Father_function);}

 

Accessing Static Fields

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

GetStaticFieldID得到java類中static 屬性ID,jfieldIDGetStatic<type>Field and SetStatic<type>Field函數族使用

參數:

clazz java類對象

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對象靜態屬性的值

 

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

設置java對象靜態屬性的值

 

 

Calling Static Methods

GetStaticMethodID

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

 

GetStaticMethodID得到java類中static方法 ID,jmethodIDCallStatic<type>Method 函數使用

 

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


上一篇:283. Move Zeroes

下一篇:二分法排序

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 建宁县| 巴彦淖尔市| 凤台县| 福鼎市| 潼关县| 商都县| 乌拉特中旗| 磐安县| 德江县| 林西县| 临安市| 安溪县| 万源市| 丹江口市| 延川县| 吉首市| 淄博市| 绥芬河市| 平陆县| 长武县| 宜都市| 横峰县| 安庆市| 绥阳县| 霸州市| 武汉市| 盈江县| 罗源县| 舞阳县| 南川市| 鄂州市| 定襄县| 平凉市| 永德县| 紫金县| 太谷县| 莒南县| 化州市| 革吉县| 安国市| 云浮市|