<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結果做處理
}
static JNINativeMethod gMethods[] =
{{ "native_XX", "()I",(void*)XX },其他函數}
對其說明一下,第一個參數是Java類中native函數的聲明,第二個參數是函數的簽名,括號內是函數的形參,後面跟的字母是返回值,因爲Java具有多態性,確定一個函數的方式是唯一的函數名+形參+返回值,而(void*)是指在C語言中函數存放的類型,一般使用(void*),XX是在C語言中實現的函數名。
這樣就實現了動態註冊。
最後說一下在Java中的自動類怎麼和C語言中的結構體對應起來。
一般的需求是在C層傳輸給Java層一個類,很簡單,使用Object.
直接給Demo
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 | Z |
byte | B |
char | C |
short | S |
int | I |
long | J |
float | F |
double | D |
類 | L全限定類名 |
數組 | [元素類型簽名 |
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 |