[Android]JNI動態註冊Java函數教程

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近在做關於JNI的項目,跟大家分享一些經驗。</span>

關於在C層靜態註冊Java層的Demo網上已經有相當多的說明了。

這裏是一個學習靜態註冊的很好的例子http://cherishlc.iteye.com/blog/1756762

可以先學習JNI的基本知識再學習下面的知識。

但是既然Java和C只是一個互調的過程,那麼只要讓JVM知道函數的對應關係就可以了。

這樣就可以不需要那麼長的函數名,而且以後對函數進行修改只需要修改頭文件就行了,比較易於擴展和閱讀。

直接開始。

首先說幾點需要注意的:

1.在我們編寫的C層的cpp文件時,它的會有生命週期函數加載的過程(我是這樣理解稱呼的)。

jint JNI_OnLoad(JavaVM* vm, void* reserved) {
}
上面這個函數會在加載的開始調用,可以在這裏方法體裏進行Java函數的動態註冊。


可以在這個函數內編寫

registerNativeMethods(env,"包名+類名"){
int result = 0;
result = env->RegisterNatives(clazz, gMethods,sizeof(gMethods) / sizeof(gMethods[0]));
//這裏對result結果做處理
}


其中gMethods是函數聲明:

static JNINativeMethod gMethods[] =
		{{ "native_XX", "()I",(void*)XX },其他函數}

對其說明一下,第一個參數是Java類中native函數的聲明,第二個參數是函數的簽名,括號內是函數的形參,後面跟的字母是返回值,因爲Java具有多態性,確定一個函數的方式是唯一的函數名+形參+返回值,而(void*)是指在C語言中函數存放的類型,一般使用(void*),XX是在C語言中實現的函數名。


這樣就實現了動態註冊。


最後說一下在Java中的自動類怎麼和C語言中的結構體對應起來。


一般的需求是在C層傳輸給Java層一個類,很簡單,使用Object.


直接給Demo

Java層:
private int native_get(Object object){};

C層
//動態註冊方法,第一個表示Java層的函數名,第二個表示(參數)返回值,第三個表示C層函數
static JNINativeMethod jMethods[] ={"native_get","(Ljava/lang/Object;)Ljava/lang/Object;",get}

//在JNI_OnLoad()中調用該動態註冊函數
result = env->RegisterNatives(clazz, jMethods,
			sizeof(jMethods) / sizeof(jMethods[0]));

//編寫C函數
JNIEXPORT jobject JNICALL get(
		JNIEnv *env, jclass thiz, jobject obj) {

	jclass cls = env->FindClass(JAVA層需要得到的包名+類名);//如 com/csdn/Student
	jfieldID issue = env->GetFieldID(cls, 類的成員變量名, 類型);//得到類的成員變量

	env->SetObjectField(obj, issue, "賦值");//給成員變量複製

	return obj;//返回對象

最後就可以在Java層調用改native函數獲取到填充了值的object對象。


需要注意的是,必須在Java層傳入一個新對象,C層只是負責給該對象填充值。


下面是一些類型在Java與C的互換


以下搬運自http://blog.csdn.net/shulianghan/article/details/18964835:

Java類型 與 類型簽名對照表 : 注意 boolean 與 long 不是大寫首字母, 分別是 Z 與 J,  類是L全限定類名, 數組是[元素類型簽名;
-- 類的簽名規則 :L + 全限定名 + ;三部分, 全限定類名以 / 分割;
Java類型 類型簽名
boolean Z
byte B
char C
short S
int I
long J
float F
double D
L全限定類名
數組 [元素類型簽名


Java數據類型 C數據類型 JNI數據類型對比 : 32位 與 64位機器可能會有出入;

Java數據類型 C本地類型 JNI定義別名
int long jint/jsize
long __int64 jlong
byte signed char jbyte
boolean unsigned char jboolean
char unsigned short jchar
short short jshort
float float jfloat
double doyble jdouble
object'
_jobject jobject

數據類型表示方法 : int數組類型 jintArray , boolean數組 jbooleanArray ...




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章