日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android — JNI注册方法说明

發布時間:2025/3/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android — JNI注册方法说明 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Jni中還可以采用RegisterNatives來注冊jni的方法,注冊以后的jni函數的命名可以不需要符合類似javah命令生成的函數的規則

RegisterNatives為JNIEnv的成員函數,聲明為:
??? jint (JNICALL *RegisterNatives) (JNIEnv *env, jclass clazz, const JNINativeMethod *methods,jint nMethods);

其對應的取消注冊的函數為聲明為:
??? jint (JNICALL *UnregisterNatives) (JNIEnv *env, jclass clazz);

在java中調用System.loadLibrary("somelib");的時候,系統會自動調用jni的函數JNI_OnLoad,
在程序退出的時候,系統卸載“somelib”,會自動調用jni的函數JNI_OnUnload,
所以我們需要在jni的接口文件中重寫這兩個函數

以上一篇建立的HelloJni的例子來說明:
先定義一個字符串,內容為類名const char* JNIT_CLASS = "com/example/hellojni/HelloJni";

再定義一個函數的說明的數組

static JNINativeMethod gMethods[] = {
?? ??? ?{"stringFromJNI", "()Ljava/lang/String;",(void*)stringFromJNI},
};

JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *jvm, void *reserved)
{
?? ?JNIEnv *env = NULL;
?? ?if ((*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_4)){
?? ??? ?return JNI_ERR;
?? ?}

??? jclass cls = (*env)->FindClass(env, JNIT_CLASS);
?? ?if (cls == NULL)
?? ?{
?? ??? ?return JNI_ERR;
?? ?}
?? ?jint nRes = (*env)->RegisterNatives(env, cls, gMethods, sizeof(gMethods)/sizeof(gMethods[0]));
?? ?if (nRes < 0)
?? ?{
?? ??? ?return JNI_ERR;
?? ?}
?? ?return JNI_VERSION_1_4;
}

JNIEXPORT void JNICALL
JNI_OnUnLoad(JavaVM *jvm, void *reserved)
{
?? ?JNIEnv *env = NULL;
?? ?if ((*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_4)){
?? ??? ?return;
?? ?}
?? ?jclass cls = (*env)->FindClass(env, JNIT_CLASS);
?? ?if (cls == NULL)
?? ?{
?? ??? ?return;
?? ?}
?? ?jint nRes = (*env)->UnregisterNatives(env, cls);
?? ?return;
}

其中JNIT_CLASS 表示的是要調用jni的java類的名稱
gMethods[]為RegisterNatives的第三個函數,表示的是所有jni的函數的集合。


JNINativeMethod是表示jni方法的結構體,其結構如下:
typedef struct {
?? ?
?? ? char *name;
???? char *signature;
????? void *fnPtr;

} JNINativeMethod;

第一個變量name為java類中native函數的名稱,
第二個變量signature為java類中native函數的java類型描述,
第三個變量fnPtr為jni中對應的函數名稱,格式為類似(void*)MethodName,

函數和變量的java類型描述可以通過命令 javap -s -p classname來獲得,classname與使用javah時寫的名稱一致,javah生成的頭文件的每個函數的注釋中也有這個描述

對于“()Ljava/lang/String;”一個描述,表示該函數沒有參數,返回值為String。括號內的是參數列表,后面跟的是返回值

java中簡單類型和jni中的描述的對應關系如下表所示:

Field DescriptorJava Language Type
Zboolean
Bbyte
Cchar
Sshort
Iint
Jlong
Ffloat
Ddouble

?

對于復雜類型,字符串描述以“L”開頭,以“;”結束,例如java中的 String ,在jni中的描述為"Ljava/lang/String;"

對于數組,以“[”開頭,接類型描述,例如int[ ],在jni中的描述為“[I”;String[ ], 對應為“[Ljava/lang/String;”;如果是數組維數增加一維,則"["增加一個,例如int[ ][ ],對應為“[[I”;

?

以上內容具體參見《The Java? Native? Interface?? Programmer’s Guide and Specification》一書,JNI中使用的各類型參見第12章 JNI TYPE


在使用JNI_OnLoad之時,我們不能把classname傳遞給jni,所以const char* JNIT_CLASS 是一個固定的名稱,我們在生成SO文件的同時這個classname就固定下來了,所以,當提供so文件的同時,需要提供一個調用該so文件的java文件,類似c++中提供dll時需要提供的.h文件一樣。

轉載于:https://www.cnblogs.com/xunbu7/p/4183368.html

總結

以上是生活随笔為你收集整理的android — JNI注册方法说明的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。