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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android JNI 使用的数据结构JNINativeMethod详解

發布時間:2025/4/16 Android 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android JNI 使用的数据结构JNINativeMethod详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Andoird 中使用了一種不同傳統Java JNI的方式來定義其native的函數。其中很重要的區別是Andorid使用了一種Java 和 C 函數的映射表數組,并在其中描述了函數的參數和返回值。這個數組的類型是JNINativeMethod,定義如下:

typedef struct {
const char* name;
const char* signature;
void*?fnPtr;
} JNINativeMethod;

第一個變量name是Java中函數的名字。

第二個變量signature,用字符串是描述了函數的參數和返回值

第三個變量fnPtr是函數指針,指向C函數。

其中比較難以理解的是第二個參數,例如

"()V"

"(II)V"

"(Ljava/lang/String;Ljava/lang/String;)V"

實際上這些字符是與函數的參數類型一一對應的。

"()" 中的字符表示參數,后面的則代表返回值。例如"()V" 就表示void Func();

"(II)V" 表示 void Func(int, int);

具體的每一個字符的對應關系如下

字符?Java類型?C類型

V??????void????????????void
Z???????jboolean?????boolean
I????????jint??????????????int
J???????jlong????????????long
D??????jdouble???????double
F??????jfloat????????????float
B??????jbyte????????????byte
C??????jchar???????????char
S??????jshort??????????short

數組則以"["開始,用兩個字符表示

[I???????jintArray??????int[]
[F?????jfloatArray????float[]
[B?????jbyteArray????byte[]
[C????jcharArray????char[]
[S????jshortArray???short[]
[D????jdoubleArray?double[]
[J?????jlongArray?????long[]
[Z????jbooleanArray?boolean[]

上面的都是基本類型。如果Java函數的參數是class,則以"L"開頭,以";"結尾中間是用"/" 隔開的包及類名。而其對應的C函數名的參數則為jobject. 一個例外是String類,其對應的類為jstring

Ljava/lang/String;?String?jstring
Ljava/net/Socket;?Socket?jobject

如果JAVA函數位于一個嵌入類,則用$作為類名間的分隔符。

例如 "(Ljava/lang/String;Landroid/os/FileUtils$FileStatus;)Z"


下邊是我在做串口通信時的代碼:

[cpp]?view plaincopyprint?
  • static?const?char?*classPathName?=?"android/serialport/SerialPort";??
  • ??
  • //注意Ljava/io/FileDescriptor;最后的分號,剛開始做時漏了這個分號,查了兩天時間,汗??
  • ??
  • static?JNINativeMethod?methods[]?=?{??
  • ??
  • ??{"open",?"(Ljava/lang/String;I)Ljava/io/FileDescriptor;",?(void*)android_serialport_SerialPort_open?},??
  • ??
  • ??{"close",?"()V",?(void*)android_serialport_SerialPort_close?},??
  • ??
  • };??
  • ??
  • ??
  • /*?
  • ?
  • ?*?Register?several?native?methods?for?one?class.?
  • ?
  • ?*/??
  • ??
  • static?int?registerNativeMethods(JNIEnv*?env,?const?char*?className,??
  • ????JNINativeMethod*?gMethods,?int?numMethods)??
  • {??
  • ????jclass?clazz;??
  • ??
  • ????clazz?=?(*env)->FindClass(env,?className);??
  • ????if?(clazz?==?NULL)??
  • ????????return?JNI_FALSE;??
  • ??
  • ????if?((*env)->RegisterNatives(env,?clazz,?gMethods,?numMethods)?<?0)??
  • ????{??
  • ????LOGE("register?nativers?error");??
  • ????????return?JNI_FALSE;??
  • ????}??
  • ??
  • ????return?JNI_TRUE;??
  • }??
  • ??
  • ??
  • ??
  • /*?
  • ?
  • ?*?Register?native?methods?for?all?classes?we?know?about.?
  • ?
  • ?*?
  • ?
  • ?*?returns?JNI_TRUE?on?success.?
  • ?
  • ?*/??
  • ??
  • static?int?registerNatives(JNIEnv*?env)??
  • ??
  • {??
  • ??
  • ??if?(!registerNativeMethods(env,?classPathName,??
  • ??
  • ?????????????????methods,?sizeof(methods)?/?sizeof(methods[0])))?{??
  • ??
  • ????return?JNI_FALSE;??
  • ??
  • ??}??
  • ??
  • ??return?JNI_TRUE;??
  • ??
  • }??
  • ??
  • /*?
  • ?
  • ?*?This?is?called?by?the?VM?when?the?shared?library?is?first?loaded.?
  • ?
  • ?*/??
  • ??
  • jint?JNI_OnLoad(JavaVM*?vm,?void*?reserved)??
  • {??
  • ????JNIEnv*?env?=?NULL;??
  • ????jint?result?=?-1;??
  • ??
  • ????LOGI("Entering?JNI_OnLoad\n");??
  • ??
  • ????if?((*vm)->GetEnv(vm,?(void**)?&env,?JNI_VERSION_1_4)?!=?JNI_OK)??
  • ????????goto?bail;??
  • ??
  • ????assert(env?!=?NULL);??
  • ??
  • ????if?(!registerNatives(env))??
  • ????????goto?bail;??
  • ??
  • ????/*?success?--?return?valid?version?number?*/??
  • ????result?=?JNI_VERSION_1_4;??
  • ??
  • bail:??
  • ????LOGI("Leaving?JNI_OnLoad?(result=0x%x)\n",?result);??
  • ????return?result;??
  • }??

  • android_serialport_SeriaPort_open的函數原型為:

    static jobject android_serialport_SerialPort_open(JNIEnv *env, jobject thiz, jstring path, jint baudrate);

    static void android_serialport_SerialPort_close(JNIEnv *env, jobject thiz);

    另外還要注意一點,如果是C++,使用的是env, 如果是C,使用的是(*env),最好參考相應系統中的代碼來寫。

    總結

    以上是生活随笔為你收集整理的Android JNI 使用的数据结构JNINativeMethod详解的全部內容,希望文章能夠幫你解決所遇到的問題。

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