JAVA 本地調用(JNI)之用dev c++簡單實現
http://blog.csdn.net/java2010czp/article/details/7460237
JNI學習積累之一 ---- 常用函數大全
本文原創,轉載請註明出處:http://blog.csdn.net/qinjuning
最近一段時間,在工作方面比較閒,分配的Bug不是很多,於是好好利用這段時間就着源代碼看了些許模塊, 主要方式
還是賊看賊看代碼, 同時利用燒機的便利,加Log觀看,基本上都能弄個臉熟 。心裏想着該寫點什麼了?可是水平不夠,再加上
包括很多真正實現地方--中間層,基本上沒看。於是乎,也就不好賣弄了。
花了幾天時間研究了下JNI,基本上知道如何使用了。照我的觀點JNI還是不難的,難得只是我們一份嘗試的心。 學習過程中,
發現關於JNI函數資料真的很少,所謂“工欲善其事,便先利其器”,整理出了這份資料,希望能幫助你克服JNI學習的坎。
主要資料來源: 百度文庫的《JNI常用函數》 。
同時對其加以了補充 。
要素 :1、 該函數大全是基於C語言方式的,對於C++方式可以直接轉換 ,例如,對於生成一個jstring類型的方法轉換分別如下:
C編程環境中使用方法爲:(*env) ->NewStringUTF(env , "123") ;
C++編程環境中(例如,VC下)則是: env ->NewStringUTF( "123") ; (使用起來更簡單)
2、關於下列有些函數中:*isCopy 的說明,例如,如下函數:
const char* GetStringUTFChars(JNIEnv*env, jstring string, jboolean *isCopy);
對第三個參數 jboolean *isCopy說明如下:
當從JNI函數GetStringUTFChars函數中返回得到字符串B時,如果B是原始字符串java.lang.String的一份拷貝,
則isCopy 被賦值爲JNI_TRUE。如果B是和原始字符串指向的是JVM中的同一份數據,則isCopy 被賦值爲JNI_FALSE。
當isCopy 爲JNI_FALSE時,本地代碼絕不能修改字符串的內容,否則JVM中的原始字符串也會被修改,這會打破Java語言
中字符串不可變的規則。
通常,我們不必關心JVM是否會返回原始字符串的拷貝,只需要爲isCopy傳遞NULL作爲參數 。
---- 以上內容來自 《JNI編程指南》
一、類操作
jclass DefineClass (JNIEnv *env, jobject loader, const jbyte *buf , jsize bufLen);
功能:從原始類數據的緩衝區中加載類。
參數: env JNI 接口指針。
loader 分派給所定義的類的類加載器。
buf 包含 .class 文件數據的緩衝區。
bufLen 緩衝區長度。
返回值:返回 Java 類對象。如果出錯則返回NULL。
拋出: ClassFormatError 如果類數據指定的類無效。
ClassCircularityError 如果類或接口是自身的超類或超接口。
OutOfMemoryError 如果系統內存不足。
jclass FindClass (JNIEnv *env, const char *name);
功能: 該函數用於加載本地定義的類。它將搜索由CLASSPATH 環境變量爲具有指定名稱的類所指定的目錄和 zip文件。
參數:env JNI 接口指針。
name 類全名(即包名後跟類名,之間由"/"分隔).如果該名稱以“[(數組簽名字符)打頭,則返回一個數組類。
返回值:返回類對象全名。如果找不到該類,則返回 NULL。
拋出: ClassFormatError 如果類數據指定的類無效。
ClassCircularityError 如果類或接口是自身的超類或超接口。
NoClassDefFoundError 如果找不到所請求的類或接口的定義。
OutOfMemoryError 如果系統內存不足。
jclass GetObjectClass (JNIEnv *env, jobject obj);
功能:通過對象獲取這個類。該函數比較簡單,唯一注意的是對象不能爲NULL,否則獲取的class肯定返回也爲NULL。
參數: env JNI 接口指針。
obj Java 類對象實例。
jclass GetSuperclass (JNIEnv *env, jclass clazz);
功能:獲取父類或者說超類 。 如果 clazz 代表類class而非類 object,則該函數返回由 clazz 所指定的類的超類。 如果 clazz
指定類 object 或代表某個接口,則該函數返回NULL。
參數: env JNI 接口指針。
clazz Java 類對象。
返回值: 由 clazz 所代表的類的超類或 NULL。
jboolean IsAssignableFrom (JNIEnv *env, jclass clazz1, jclass clazz2);
功能:確定 clazz1 的對象是否可安全地強制轉換爲clazz2。
參數: env JNI 接口指針。
clazz1 第一個類參數。
clazz2 第二個類參數。
返回值: 下列某個情況爲真時返回 JNI_TRUE:
1、 第一及第二個類參數引用同一個 Java 類。
2、 第一個類是第二個類的子類。
3、 第二個類是第一個類的某個接口。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
二、異常操作
jint Throw(JNIEnv *env, jthrowable obj);
功能:拋出 java.lang.Throwable 對象。
參數: env JNI 接口指針。
obj java.lang.Throwable 對象。
返回值: 成功時返回 0,失敗時返回負數。
拋出: java.lang.Throwable 對象 obj。
jint ThrowNew (JNIEnv *env , jclass clazz, const char *message);
功能:利用指定類的消息(由 message 指定)構造異常對象並拋出該異常。
參數: env JNI 接口指針。
clazz java.lang.Throwable 的子類。
message 用於構造java.lang.Throwable對象的消息。
返回值: 成功時返回 0,失敗時返回負數。
拋出: 新構造的 java.lang.Throwable 對象。
jthrowable ExceptionOccurred (JNIEnv *env);
功能:確定是否某個異常正被拋出。在平臺相關代碼調用 ExceptionClear() 或 Java 代碼處理該異常前,異常將始終保持
拋出狀態。
參數: env JNI 接口指針。
返回值: 返回正被拋出的異常對象,如果當前無異常被拋出,則返回NULL。
void ExceptionDescribe (JNIEnv *env);
功能:將異常及堆棧的回溯輸出到系統錯誤報告信道(例如 stderr)。該例程可便利調試操作。
參數:env JNI 接口指針。
void ExceptionClear (JNIEnv *env);
功能:清除當前拋出的任何異常。如果當前無異常,則此例程不產生任何效果。
參數: env JNI 接口指針。
void FatalError (JNIEnv *env, const char *msg);
功能:拋出致命錯誤並且不希望虛擬機進行修復。該函數無返回值。
參數: env JNI 接口指針。
msg 錯誤消息。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
三、全局及局部引用
jobject NewGlobalRef (JNIEnv *env, jobject obj);
功能:創建 obj 參數所引用對象的新全局引用。obj 參數既可以是全局引用,也可以是局部引用。全局引用通過調用
DeleteGlobalRef() 來顯式撤消。
參數:env JNI 接口指針。
obj 全局或局部引用。
返回值: 返回全局引用。如果系統內存不足則返回 NULL。
void DeleteGlobalRef (JNIEnv *env, jobject globalRef);
功能: 刪除 globalRef 所指向的全局引用。
參數: env JNI 接口指針。
globalRef 全局引用。
void DeleteLocalRef (JNIEnv *env, jobject localRef);
功能: 刪除 localRef所指向的局部引用。
參數: env JNI 接口指針。
localRef 局部引用。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
四、對象操作
jobject AllocObject (JNIEnv *env, jclass clazz);
功能:分配新 Java 對象而不調用該對象的任何構造函數。返回該對象的引用。clazz 參數務必不要引用數組類。
參數: env JNI 接口指針。
clazz Java 類對象。
返回值: 返回 Java 對象。如果無法構造該對象,則返回NULL。
拋出: InstantiationException:如果該類爲一個接口或抽象類。
OutOfMemoryError:如果系統內存不足。
jobject NewObject (JNIEnv *env , jclass clazz, jmethodID methodID, ...); //參數附加在函數後面
jobject NewObjectA (JNIEnv *env , jclassclazz, jmethodID methodID, jvalue *args); //參數以指針形式附加
jobjec tNewObjectV (JNIEnv *env , jclassclazz, jmethodID methodID, va_list args); //參數以"鏈表"形式附加
功能:構造新 Java 對象。方法 ID指示應調用的構造函數方法。注意:該 ID特指該類class的構造函數ID , 必須通過調用
GetMethodID() 獲得,且調用時的方法名必須爲 <init>,而返回類型必須爲 void (V)。clazz參數務必不要引用數組類。
參數: env JNI 接口指針。
clazz Java 類對象。
methodID 構造函數的方法 ID。
NewObject 的其它參數: 傳給構造函數的參數,可以爲空 。
NewObjectA 的其它參數: args:傳給構造函數的參數數組。
NewObjectV 的其它參數: args:傳給構造函數的參數 va_list。
返回值: 返回 Java 對象,如果無法構造該對象,則返回NULL。
拋出: InstantiationException 如果該類爲接口或抽象類。
OutOfMemoryError 如果系統內存不足。
構造函數拋出的任何異常。
jclass GetObjectClass (JNIEnv *env, jobject obj);
功能:返回對象的類。
參數: env JNI 接口指針。
obj Java 對象(不能爲 NULL)。
返回值: 返回 Java 類對象。
jboolean IsInstanceOf (JNIEnv *env, jobject obj, jclass clazz);
功能:測試對象是否爲某個類的實例。
參數: env JNI 接口指針。
obj Java 對象。
clazz Java 類對象。
返回值:如果可將 obj 強制轉換爲 clazz,則返回 JNI_TRUE。否則返回 JNI_FALSE。NULL 對象可強制轉換爲任何類。
jbooleanIsSameObject (JNIEnv *env, jobjectref1, jobject ref2);
功能:測試兩個引用是否引用同一 Java 對象。
參數: env JNI 接口指針。
ref1 Java 對象。
ref2 Java 對象。
返回值: 如果 ref1 和 ref2 引用同一 Java 對象或均爲 NULL,則返回 JNI_TRUE。否則返回 JNI_FALSE。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
五、 字符串操作
jstring NewString (JNIEnv *env, const jchar *unicodeChars, jsize len);
功能:利用 Unicode 字符數組構造新的 java.lang.String 對象。
參數: env:JNI 接口指針。
unicodeChars:指向 Unicode 字符串的指針。
len:Unicode 字符串的長度。
返回值: Java 字符串對象。如果無法構造該字符串,則爲NULL。
拋出: OutOfMemoryError:如果系統內存不足。
jsize GetStringLength (JNIEnv *env, jstring string);
功能:返回 Java 字符串的長度(Unicode 字符數)。
參數: env:JNI 接口指針。
string:Java 字符串對象。
返回值: Java 字符串的長度。
const jchar * GetStringChars (JNIEnv*env, jstring string, jboolean *isCopy);
功能:返回指向字符串的 Unicode 字符數組的指針。該指針在調用 ReleaseStringchars() 前一直有效。
如果 isCopy 非空,則在複製完成後將 *isCopy 設爲 JNI_TRUE。如果沒有複製,則設爲JNI_FALSE。
參數: env:JNI 接口指針。
string:Java 字符串對象。
isCopy:指向布爾值的指針。
返回值: 指向 Unicode 字符串的指針,如果操作失敗,則返回NULL。
void ReleaseStringChars (JNIEnv *env, jstring string, const jchar *chars);
功能:通知虛擬機平臺相關代碼無需再訪問 chars。參數chars 是一個指針,可通過 GetStringChars() 從 string 獲得。
參數: env:JNI 接口指針。
string:Java 字符串對象。
chars:指向 Unicode 字符串的指針。
jstring NewStringUTF (JNIEnv *env, const char *bytes);
功能:利用 UTF-8 字符數組構造新 java.lang.String 對象。
參數: env:JNI 接口指針。如果無法構造該字符串,則爲 NULL。
bytes:指向 UTF-8 字符串的指針。
返回值:Java 字符串對象。如果無法構造該字符串,則爲NULL。
拋出: OutOfMemoryError:如果系統內存不足。
jsize GetStringUTFLength (JNIEnv *env, jstring string);
功能:以字節爲單位返回字符串的 UTF-8 長度。
參數: env:JNI 接口指針。
string:Java 字符串對象。
返回值: 返回字符串的 UTF-8
const char* GetStringUTFChars (JNIEnv*env, jstring string, jboolean *isCopy);
功能:返回指向字符串的 UTF-8 字符數組的指針。該數組在被ReleaseStringUTFChars() 釋放前將一直有效。 如果 isCopy
不是 NULL,*isCopy 在複製完成後即被設爲 JNI_TRUE。如果未複製,則設爲 JNI_FALSE。
參數: env:JNI 接口指針。
string:Java 字符串對象。
isCopy:指向布爾值的指針。
返回值: 指向 UTF-8 字符串的指針。如果操作失敗,則爲 NULL。
void ReleaseStringUTFChars (JNIEnv *env, jstring string, const char *utf);
功能:通知虛擬機平臺相關代碼無需再訪問 utf。utf 參數是一個指針,可利用 GetStringUTFChars() 獲得。
參數: env:JNI 接口指針。
string:Java 字符串對象。
utf:指向 UTF-8 字符串的指針。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
六、數組操作
jsize GetArrayLength (JNIEnv *env, jarray array);
功能:返回數組中的元素數。
參數: env:JNI 接口指針。
array:Java 數組對象。
返回值: 數組的長度。
jarray NewObjectArray (JNIEnv *env, jsize length, jclass elementClass, jobject initialElement);
功能:構造新的數組,它將保存類 elementClass 中的對象。所有元素初始值均設爲 initialElement。
參數: env:JNI 接口指針。
length:數組大小。
elementClass:數組元素類。
initialElement:初始值。 可以爲NULL 。
返回值:Java 數組對象。如果無法構造數組,則爲 NULL。
拋出: OutOfMemoryError:如果系統內存不足。
說明: 使用該函數時,爲了便於易操作性,我們一般可以用jobjectArray數組類型或得返回值,例如:
jobjectArray objArray = env->NewObjectArray ( );
//操作該對象
env->GetObjectArrayElement (objArray, 0);//獲得該object數組在索引0處的值 ,(可以強制轉換類型).
jobject GetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index);
功能:返回 Object 數組的元素。
參數: env:JNI 接口指針。
array:Java 數組。
index:數組下標。
返回值: Java 對象。
拋出: ArrayIndexOutOfBoundsException:如果 index 不是數組中的有效下標。
void SetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index, jobject value);
功能:設置 Object 數組的元素。
參數: env:JNI 接口指針。
array:Java 數組。
index:數組下標。
value:新值。
拋出: ArrayIndexOutOfBoundsException:如果 index 不是數組中的有效下標。
ArrayStoreException:如果 value 的類不是數組元素類的子類。
New<PrimitiveType>Array方法類型
NativeType New<PrimitiveType>Array (JNIEnv *env, ArrayType array, jboolean*isCopy);
說明: 用於構造新基本類型數組對象的一系列操作。下表說明了特定的基本類型數組構造函數。用戶應把
New<PrimitiveType>Array 替換爲某個實際的基本類型數組構造函數例程名(見下表),然後將 ArrayType替換爲
該例程相應的數組類型。
參數: env : JNI 接口指針。
length:數組長度。
返回值: Java 數組。如果無法構造該數組,則爲 NULL。
New<PrimitiveType>Array 方法組 數組類型
NewBooleanArray() jbooleanArray
NewByteArray() jbyteArray
NewCharArray() jcharArray
NewShortArray() jshortArray
NewIntArray() jintArray
NewLongArray() jlongArray
NewFloatArray() jfloatArray
NewDoubleArray() jdoubleArray
Get<PrimitiveType>ArrayElements 方法類型
NativeType *Get<PrimitiveType>ArrayElements (JNIEnv *env, ArrayType array, jboolean*isCopy);
說明:一組返回基本類型數組體的函數。結果在調用相應的 Release<PrimitiveType>ArrayElements()函數前將一直有效。
由於返回的數組可能是 Java 數組的副本,因此對返回數組的更改不必在基本類型數組中反映出來,直到調用了
Release<PrimitiveType>ArrayElements()。 如果 isCopy 不是 NULL,*isCopy 在複製完成後即被設爲 JNI_TRUE。如果
未複製,則設爲 JNI_FALSE。
使用說明:
將 Get<PrimitiveType>ArrayElements 替換爲表中某個實際的基本類型元素訪問器例程名。
將 ArrayType 替換爲對應的數組類型。
將 NativeType 替換爲該例程對應的本地類型。
參數: env:JNI 接口指針。
array:Java 字符串對象。
isCopy:指向布爾值的指針。
返回值: 返回指向數組元素的指針,如果操作失敗,則爲 NULL。
不管布爾數組在 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 Release<PrimitiveType>ArrayElements (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 參數以確保固定的數組和複製的數組保持一致。其它選項可以使編程人員進一步
控制內存管理,但使用時務必慎重。
使用說明:
將 ArrayType 替換爲對應的數組類型。
將 NativeType 替換爲該例程對應的本地類型。
參數: env:JNI 接口指針。
array:Java 數組對象。
elems:指向數組元素的指針。
mode:釋放模式。
Release<PrimitiveType>ArrayElements 方法組 數組類型 本地類型
ReleaseBooleanArrayElements() jbooleanArray jboolean
ReleaseByteArrayElements() jbyteArray jbyte
ReleaseCharArrayElements() jcharArray jchar
ReleaseShortArrayElements() jshortArray jshort
ReleaseIntArrayElements() jintArray jint
ReleaseLongArrayElements() jlongArray jlong
ReleaseFloatArrayElements() jfloatArray jfloat
ReleaseDoubleArrayElements() jdoubleArray jdouble
Get<PrimitiveType>ArrayRegion 方法類型
void Get<PrimitiveType>ArrayRegion (JNIEnv *env, ArrayType array, jsize start, jsize len, NativeType *buf);
功能:將基本類型數組某一區域複製到緩衝區中的一組函數。
使用說明:
將 Get<PrimitiveType>ArrayRegion 替換爲下表的某個實際基本類型元素訪問器例程名。
將 ArrayType 替換爲對應的數組類型。
將 NativeType 替換爲該例程對應的本地類型。
參數: env:JNI 接口指針。
array:Java 指針。
start:起始下標。
len:要複製的元素數。
buf:目的緩衝區。
拋出: ArrayIndexOutOfBoundsException:如果區域中的某個下標無效。
方法族如下:
Get<PrimitiveType>ArrayRegion方法 數組類型 本地類型
GetBooleanArrayRegion() jbooleanArray jboolean
GetByteArrayRegion() jbyteArray jbyte
GetCharArrayRegion() jcharArray jchar
GetShortArrayRegion() jshortArray jhort
GetIntArrayRegion() jintArray jint
GetLongArrayRegion() jlongArray jlong
GetFloatArrayRegion() jfloatArray jloat
GetDoubleArrayRegion() jdoubleArray jdouble
Set<PrimitiveType>ArrayRegion 方法類型
void Set<PrimitiveType>ArrayRegion (JNIEnv *env, ArrayType array, jsize start, jsize len, NativeType *buf);
功能:將基本類型數組的某一區域從緩衝區中複製回來的一組函數。
使用說明: 將 Set<PrimitiveType>ArrayRegion 替換爲表中的實際基本類型元素訪問器例程名。
將 ArrayType 替換爲對應的數組類型。
將 NativeType 替換爲該例程對應的本地類型。
參數: env:JNI 接口指針。
array: Java 數組。
start:起始下標。
len:要複製的元素數。
buf:源緩衝區。
拋出: ArrayIndexOutOfBoundsException:如果區域中的某個下標無效。
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
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
六、訪問對象的屬性和方法
1、實例屬性的訪問
jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig);
功能:返回類的實例(非靜態)域的屬性 ID。該域由其名稱及簽名指定。訪問器函數的Get<type>Field 及 Set<type>Field
系列使用域 ID 檢索對象域。GetFieldID() 不能用於獲取數組的長度域。應使用GetArrayLength()。
參數: env:JNI 接口指針。
clazz:Java 類對象。
name: 該屬性的Name名稱
sig: 該屬性的域簽名。
返回值:屬性ID。如果操作失敗,則返回NULL。
拋出: NoSuchFieldError:如果找不到指定的域。
ExceptionInInitializerError:如果由於異常而導致類初始化程序失敗。
OutOfMemoryError:如果系統內存不足。
Get<type>Field 例程
NativeType Get<type>Field (JNIEnv*env, jobject obj, jfieldID fieldID);
功能:該訪問器例程系列返回對象的實例(非靜態)域的值。要訪問的域由通過調用GetFieldID() 而得到的域 ID 指定。
參數: env:JNI 接口指針。
obj:Java 對象(不能爲 NULL)。
fieldID:有效的域 ID。
返回值: 屬性的內容。
Get<type>Field 例程名 本地類型
GetObjectField() jobject
GetBooleanField() jboolean
GetByteField() jbyte
GetCharField() jchar
GetShortField() jshort
GetIntField() jint
GetLongField() jlong
GetFloatField() jfloat
GetDoubleField() jdouble
Set<type>Field 方法族
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 方法族 本地類型
SetObjectField() jobject
SetBooleanField() jboolean
SetByteField() jbyte
SetCharField() jchar
SetShortField() jshort
SetIntField() jint
SetLongField() jlong
SetFloatField() jfloat
SetDoubleField() jdouble
2、靜態屬性的訪問 :也存在相同的方法,
jfieldID GetStaticFieldID (JNIEnv *env,jclass clazz, const char *name, const char *sig);
NativeType GetStatic<type>Field (JNIEnv*env,jclass classzz , jfieldID fieldID);
void SetStatic<type>Field (JNIEnv *env,jclassclasszz, jfieldID fieldID, NativeType value);
它們與實例屬性的唯一區別在於第二個參數jclass classzz代表的是類引用,而不是類實例。
3、調用實例方法
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:方法名。
sig:方法的簽名。
返回值: 方法 ID,如果找不到指定的方法,則爲 NULL。
拋出: NoSuchMethodError:如果找不到指定方法。
ExceptionInInitializerError:如果由於異常而導致類初始化程序失敗。
OutOfMemoryError:如果系統內存不足。
Call<type>Method 例程 、Call<type>MethodA 例程 、Call<type>MethodV 例程
NativeType Call<type>Method (JNIEnv*en v, 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。
返回值: 返回調用 Java 方法的結果。
拋出: 執行 Java 方法時拋出的異常。
下表根據結果類型說明了各個方法類型。用戶應將Call<type>Method 中的 type 替換爲所調用方法的Java 類型(或使用表
中的實際方法名),同時將 NativeType 替換爲該方法相應的本地類型。省略掉了其他兩種類型。
Java層返回值 方法族 本地返回類型NativeType
返回值爲void : CallVoidMethod( ) A / V (無)
返回值爲引用類型: CallObjectMethod( ) jobect
返回值爲boolean : CallBooleanMethod ( ) jboolean
返回值爲byte : CallByteMethod( ) jbyte
返回值爲char : CallCharMethod( ) jchar
返回值爲short CallShortMethod( ) jshort
返回值爲int : CallIntMethod( ) jint
返回值爲long: CallLongMethod() jlong
返回值爲float : CallFloatMethod() jfloat
返回值爲double: CallDoubleMethod() jdouble
4、調用靜態方法:也存在如下方法羣,
jfieldID GetStaticMethodID (JNIEnv *env,jclass clazz, const char *name, const char *sig);
NativeType Call<type>Method (JNIEnv*env,jclass classzz , jfieldID fieldID);
它們與於實例方法的唯一區別在於第二個參數jclass classzz代表的是類引用,而不是類實例。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
七、註冊本地方法
jint RegisterNatives (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods);
功能:向 clazz 參數指定的類註冊本地方法。methods 參數將指定 JNINativeMethod 結構的數組,其中包含本地方法的名稱、
簽名和函數指針。nMethods 參數將指定數組中的本地方法數。JNINativeMethod 結構定義如下所示:
typedef struct {
char *name;
char *signature;
void *fnPtr;
} JNINativeMethod;
函數指針通常必須有下列簽名:
ReturnType (*fnPtr)(JNIEnv *env, jobject objectOrClass, ...);
參數: env:JNI 接口指針。
clazz:Java 類對象。
methods:類中本地方法和具體實現方法的映射指針。
nMethods:類中的本地方法數。
返回值: 成功時返回 "0";失敗時返回負數。
拋出: NoSuchMethodError:如果找不到指定的方法或方法不是本地方法。
jint UnregisterNatives (JNIEnv *env, jclass clazz);
功能: 取消註冊類的本地方法。類將返回到鏈接或註冊了本地方法函數前的狀態。 該函數不應在常規平臺相關代碼中使用。
相反,它可以爲某些程序提供一種重新加載和重新鏈接本地庫的途徑。
參數: env:JNI 接口指針。
clazz:Java 類對象。
返回值: 成功時返回“0”;失敗時返回負數。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
其實,JNI方面的書籍還是比較少的,建議大家看看《JNI編程指南》,算的上個入門書籍吧,指望你能耐心點看。
下一篇,我會繼續整理JNI的基礎知識,包括類型映射、域簽名等;