日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

android — JNI注册方法说明

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

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

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

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

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

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

再定義一個函數(shù)的說明的數(shù)組

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 表示的是要調(diào)用jni的java類的名稱
gMethods[]為RegisterNatives的第三個函數(shù),表示的是所有jni的函數(shù)的集合。


JNINativeMethod是表示jni方法的結(jié)構(gòu)體,其結(jié)構(gòu)如下:
typedef struct {
?? ?
?? ? char *name;
???? char *signature;
????? void *fnPtr;

} JNINativeMethod;

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

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

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

java中簡單類型和jni中的描述的對應(yīng)關(guān)系如下表所示:

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

?

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

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

?

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


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

轉(zhuǎn)載于:https://www.cnblogs.com/xunbu7/p/4183368.html

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。