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

歡迎訪問 生活随笔!

生活随笔

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

Android

Android JNI 传递对象

發布時間:2025/6/17 Android 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android JNI 传递对象 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JNI初步入門后,在傳遞數據的時候,遇到一個需求:有多個數據需要在Java與C代碼之間進行傳遞。如果都做為函數參數傳入,則函數很長很難看,并且多個數據的返回也不好實現。所以想到了把數據打包后傳遞。這在C語言中就是結構體,在Java中就是類了。
我們要做的工作就是,先確定要傳遞的數據,然后相應在C與Java中定義相應的數據類型,然后通過JNI進行數據對應。下面以一個例程來逐步說明。

為了更好的說明各種數據類型的轉換示例,我們的數據包含整型、字符串、浮點數、字符、布爾值、數組。

在Java端定義類:

public class ParamInfo {public boolean boolValue;public char charValue; public double doubleValue; public int intValue; public byte[] array; public String str; }

在C端定義結構體:

typedef struct{bool boolValue;char charValue;double doubleValue; int intValue; char array[255]; char str[255]; }ParamInfo;

jni接口中并不要求兩邊的變量名一致,或者類名與結構體名一致,只是我們為了邏輯清晰,最好將名稱定義的一致,以便于在后續編寫代碼的過程中更好的將相應數據一一對應起來。

在C代碼中獲取Java代碼傳遞的參數:

  • 以獲取類中一個整型值為例:
    //獲取Java中的實例類ParamInfo
jclass jcInfo = env->FindClass("com/example/helloworld/ParamInfo");
  • 1

其中,com/example/helloworld 是包名對應路徑,ParamInfo是包含數據接口的類名。

  • 獲取類中一個整型變量intValue的定義
jfieldID jfi = env->GetFieldID(jcInfo, "intValue", "I");
  • 1
  • 獲取實例的變量intValue的值,其中jobj即參數中攜帶數據的對象:
paramInfo.intValue = env->GetIntField(jobj, jfi);
  • 1

在C代碼中設置向Java端傳遞的參數:

以傳遞結構體中一個整型值為例:

  • 先設置結構體中整型值:
paramInfo.intValue = 8;
  • 1
  • 獲取Java中的實例類ParamInfo
jclass jcInfo = env->FindClass("com/example/helloworld/ParamInfo");
  • 1

其中com/example/helloworld 是包名對應路徑,ParamInfo是包含數據接口的類名。

  • 獲取類中一個整型變量intValue的定義
jfieldID jfi = env->GetFieldID(jcInfo, "intValue", "I");
  • 1
  • 創建新的對象
jobject joInfo = env->AllocObject(jcInfo);
  • 1
  • 設置實例的變量intValue的值
env->SetIntField(joInfo, jfi, paramInfo.intValue);
  • 1
  • 最后返回該對象
return joInfo;
  • 1

其余數據類型值的訪問,都是類似的步驟。注意 GetFieldID()的第3個參數的取值,是數據類型的簽名標識,具體取值見下面表格:

請查看下表:

Java類型符號
booleanZ
byteB
charC
shortS
intI
longL
floatF
doubleD
voidV
object對象LClassName; L類名;
Arrays[array-type [數組類型
methods方法(argument-types)return-type (參數類型)返回類型

native代碼

知道這些了,就可以進行我們native代碼的書寫了,如下:

// Java 類向C結構體類型轉換 JNIEXPORT jint JNICALL Java_com_example_helloworld_JniClient_setInfo(JNIEnv *env, jobject jo, jobject jobj) {ParamInfo paramInfo;//獲取Java中的實例類ParamInfojclass jcInfo = env->FindClass("com/example/helloworld/ParamInfo"); //獲取類中每一個變量的定義 //boolean boolValue jfieldID jfb = env->GetFieldID(jcInfo, "boolValue", "Z"); //char charValue jfieldID jfc = env->GetFieldID(jcInfo, "charValue", "C"); //double charValue jfieldID jfd = env->GetFieldID(jcInfo, "doubleValue", "D"); //int intValue jfieldID jfi = env->GetFieldID(jcInfo, "intValue", "I"); //byte[] array jfieldID jfa = env->GetFieldID(jcInfo, "array", "[B"); //String str jfieldID jfs = env->GetFieldID(jcInfo, "str", "Ljava/lang/String;"); //獲取實例的變量boolValue的值 paramInfo.boolValue = env->GetBooleanField(jobj, jfb); //獲取實例的變量charValue的值 paramInfo.charValue = env->GetCharField(jobj, jfc); //獲取實例的變量doubleValue的值 paramInfo.doubleValue = env->GetDoubleField(jobj, jfd); //獲取實例的變量intValue的值 paramInfo.intValue = env->GetIntField(jobj, jfi); //獲取實例的變量array的值 jbyteArray ja = (jbyteArray)env->GetObjectField(jobj, jfa); int nArrLen = env->GetArrayLength(ja); char *chArr = (char*)env->GetByteArrayElements(ja, 0); memcpy(paramInfo.array, chArr, nArrLen); //獲取實例的變量str的值 jstring jstr = (jstring)env->GetObjectField(jobj, jfs); const char* pszStr = (char*)env->GetStringUTFChars(jstr, 0); strcpy(paramInfo.str, pszStr); //日志輸出 LOGI("paramInfo.array=%s, paramInfo.boolValue=%d, paramInfo.charValue=%c\n", paramInfo.array, paramInfo.boolValue, paramInfo.charValue); LOGI("paramInfo.doubleValue=%lf, paramInfo.intValue=%d, paramInfo.str=%s\n", paramInfo.doubleValue, paramInfo.intValue, paramInfo.str); return 0; } // C結構體類型向Java 類轉換 JNIEXPORT jobject JNICALL Java_com_example_helloworld_JniClient_getInfo (JNIEnv *env, jobject jo) { char chTmp[] = "Test array"; int nTmpLen = strlen(chTmp); //將C結構體轉換成Java類 ParamInfo paramInfo; memset(paramInfo.array, 0, sizeof(paramInfo.array)); memcpy(paramInfo.array, chTmp, strlen(chTmp)); paramInfo.boolValue = true; paramInfo.charValue = 'B'; paramInfo.doubleValue = 2.7182; paramInfo.intValue = 8; strcpy(paramInfo.str, "Hello from JNI"); LOGI("paramInfo.array=%s, paramInfo.boolValue=%d, paramInfo.charValue=%c\n", paramInfo.array, paramInfo.boolValue, paramInfo.charValue); //獲取Java中的實例類 jclass jcInfo = env->FindClass("com/example/helloworld/ParamInfo"); //獲取類中每一個變量的定義 //boolean boolValue jfieldID jfb = env->GetFieldID(jcInfo, "boolValue", "Z"); //char charValue jfieldID jfc = env->GetFieldID(jcInfo, "charValue", "C"); //double doubleValue jfieldID jfd = env->GetFieldID(jcInfo, "doubleValue", "D"); //int intValue jfieldID jfi = env->GetFieldID(jcInfo, "intValue", "I"); //byte[] array jfieldID jfa = env->GetFieldID(jcInfo, "array", "[B"); //String str jfieldID jfs = env->GetFieldID(jcInfo, "str", "Ljava/lang/String;"); //創建新的對象 jobject joInfo = env->AllocObject(jcInfo); //給類成員賦值 env->SetBooleanField(joInfo, jfb, paramInfo.boolValue); env->SetCharField(joInfo, jfc, (jchar)paramInfo.charValue); env->SetDoubleField(joInfo, jfd, paramInfo.doubleValue); env->SetIntField(joInfo, jfi, paramInfo.intValue); //數組賦值 jbyteArray jarr = env->NewByteArray(nTmpLen); jbyte *jby = env->GetByteArrayElements(jarr, 0); memcpy(jby, paramInfo.array, nTmpLen); env->SetByteArrayRegion(jarr, 0, nTmpLen, jby); env->SetObjectField(joInfo, jfa, jarr); //字符串賦值 jstring jstrTmp = env->NewStringUTF(paramInfo.str); env->SetObjectField(joInfo, jfs, jstrTmp); return joInfo; }

Java端測試代碼:

// 動態加載C庫System.loadLibrary("HelloWorld");//進行對象的jni傳遞ParamInfo paramInfoSet = new ParamInfo(); byte[] b = new byte[10]; for (int i = 0; i < 9; i++) { b[i] = (byte) (i + 97); } paramInfoSet.array = b; paramInfoSet.boolValue = false; paramInfoSet.charValue = 'C'; paramInfoSet.doubleValue = 3.14; paramInfoSet.intValue = 2016; paramInfoSet.str = "Hello from Java"; Log.i("Hello", "log: to access lib"); JniClient.setInfo(paramInfoSet); Log.i("Hello", "log: after setInfo"); //進行對象的jni接收 ParamInfo paramInfoGet = JniClient.getInfo(); Log.i("Hello", "log: paramInfoGet.boolValue=" + paramInfoGet.boolValue + " paramInfoGet.charValue=" + paramInfoGet.charValue + " paramInfoGet.doubleValue=" + paramInfoGet.doubleValue); Log.i("Hello", "log: paramInfoGet.intValue=" + paramInfoGet.intValue + " paramInfoGet.array=" + new String (paramInfoGet.array) + " paramInfoGet.str=" + paramInfoGet.str); //將收到的字符串顯示到界面上 TextView tv_say_hello = (TextView) findViewById(R.id.tv_say_hello); tv_say_hello.setText(paramInfoGet.str); Log.i("Hello", "log: finish");
  • 1

最后輸出的日志信息:

06-25 17:04:25.740: I/Hello(19039): log: to access lib 06-25 17:04:25.740: I/logfromc(19039): paramInfo.array=abcdefghi, paramInfo.boolValue=0, paramInfo.charValue=C 06-25 17:04:25.740: I/logfromc(19039): paramInfo.doubleValue=3.140000, paramInfo.intValue=2016, paramInfo.str=Hello from Java 06-25 17:04:25.740: I/Hello(19039): log: after setInfo 06-25 17:04:25.740: I/logfromc(19039): paramInfo.array=Test array, paramInfo.boolValue=1, paramInfo.charValue=B 06-25 17:04:25.740: I/Hello(19039): log: paramInfoGet.boolValue=true paramInfoGet.charValue=B paramInfoGet.doubleValue=2.7182 06-25 17:04:25.740: I/Hello(19039): log: paramInfoGet.intValue=8 paramInfoGet.array=Test array paramInfoGet.str=Hello from JNI 06-25 17:04:25.740: I/Hello(19039): log: finish

可以看出,java設置的數值,已經成功傳遞到C端;而C程序設置的數據,也成功回傳到java端了。

demo下載:

http://download.csdn.net/detail/lintax/9559413

轉載于:https://www.cnblogs.com/Free-Thinker/p/6829136.html

總結

以上是生活随笔為你收集整理的Android JNI 传递对象的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 视频黄色免费 | 三级国产三级在线 | 久久性生活视频 | 加勒比hezyo黑人专区 | 裸体视频软件 | 人妻久久久一区二区三区 | 精品无码久久久久久久久果冻 | 成人一区二区在线观看 | 亚洲精品国产精品乱码视色 | 久久婷婷精品 | 最新中文字幕在线视频 | 欧美人喂奶吃大乳 | 国产精品自拍亚洲 | 在线观看亚洲一区 | 风间ゆみ大战黑人 | 狠狠操在线| 天天操免费视频 | 黄色不打码视频 | 最新免费av | 五月激情开心网 | 午夜电影一区 | 亚洲高清在线播放 | 日韩精品第一 | 都市激情国产精品 | 美女被男人桶出白浆喷水 | 日本大奶子视频 | 亚洲第二色| 精品国产99久久久久久宅男i | 日韩av在线播放一区 | 色av网| 日本在线视频一区 | 欧美色涩| 黄色三级免费观看 | 国产在线播放91 | 日本三级黄色大片 | 秋霞成人午夜伦在线观看 | 欧美精品成人一区二区在线观看 | 麻豆网站在线免费观看 | 色网在线免费观看 | 久久久国产精华液999999 | 成人网站免费观看 | 求av网址| 中文字幕在线观看一区 | 国产精品一区二区三区四区视频 | 夜夜操天天 | 91猎奇在线观看 | 欧美性爱视频久久 | 青青一区二区 | 91看片淫黄大片91桃色 | 亚洲第一免费播放区 | 中国在线观看片免费 | 久草青青视频 | 成人教育av在线 | 免费成人美女女 | 99re这里只有精品首页 | 国产真实乱 | 艳妇av| 青春草国产视频 | 韩国中文三级hd字幕 | 丰满人妻一区二区三区精品高清 | 国产成人aⅴ | 成人久久久久久久 | 激情综合色| 国产精品对白 | 欧洲一级黄色片 | 欧美美女在线观看 | 久久久精品美女 | 久人人| 亚洲欧美在线综合 | 一区二区精品区 | 国产精品12区 | 欧美日韩xxx | 麻豆精品国产传媒av | 高清日韩一区 | 18av在线视频| 亚洲天堂五码 | 久久天堂影院 | 中文字幕日韩人妻在线视频 | 97视频国产 | 亚洲成色| 国产在线观看成人 | 色乱码一区二区三区 | 丁香激情六月 | 牛牛澡牛牛爽一区二区 | 蜜臀av一区二区 | 亚洲第一男人天堂 | 亚洲一区二区三区免费在线观看 | 手机成人免费视频 | 欧美性一区二区 | 中文字幕一区二区视频 | 日韩av在线播放一区 | 边啃奶头边躁狠狠躁 | 成人免费视频国产 | 日韩人妻一区二区三区 | 亚洲一区二区三区四区五区xx | 亚洲熟女一区二区三区 | 黄色在线不卡 | 亚洲一区播放 | 黄网址在线观看 |