近期为android 端项目包装一些c++代码,故学习ndk相关知识,现总结如下:
1,java与c++类型参照图:
2,此测试中使用的java类:
1 package com.dasea.test.core; 2 public class TestSetData { 3 // 主要是类ID和字段ID,方法ID的缓存 4 static { 5 OnNative(); 6 } 7 8 public native static void OnNative(); 9 10 public boolean bData;11 public double dData;12 public int iData;13 public byte cData;14 public String sData;15 public byte byteArr[];16 17 public int intArr[];18 19 public TestSetData() {20 // TODO Auto-generated constructor stub21 bData = true;22 dData = 100.11;23 iData = 333;24 cData = 100;25 sData = "20150204";26 byteArr = new byte[10];27 for (int i = 0; i < byteArr.length; i++) {28 byteArr[i] = '2';29 }30 31 intArr = new int[10];32 for (int i = 0; i < intArr.length; i++) {33 intArr[i] = i * 10;34 }35 }36 }
3,使用类接口定义:
①java端:
public native TestSetData testData(TestSetData obj);
②c++端:
JNIEXPORT jobject JNICALL Java_com_dasea_test_core_JniDemo_testData(JNIEnv* env, jobject obj, jobject jobj) ;
4,完整c++端接口实现:
1 JNIEXPORT jobject JNICALL Java_com_dasea_test_core_JniDemo_testData(JNIEnv* env, jobject obj, jobject jobj){ 2 DEBUG_OUT("test set data start"); 3 4 jclass jcSetDataMgr = env->FindClass("com/dasea/test/core/TestSetData"); 5 if(NULL == jcSetDataMgr){ 6 DEBUG_OUT("Not find class!"); 7 return NULL; 8 } 9 DEBUG_OUT("Find class succ!");10 11 jfieldID jfbdata = env->GetFieldID(jcSetDataMgr, "bData", "Z");12 if(NULL == jfbdata){13 DEBUG_OUT("jfbdata fail!");14 }15 jfieldID jfddata = env->GetFieldID(jcSetDataMgr, "dData", "D");16 if(NULL == jfbdata){17 DEBUG_OUT("jfddata fail!");18 }19 jfieldID jfidata = env->GetFieldID(jcSetDataMgr, "iData", "I");20 if(NULL == jfbdata){21 DEBUG_OUT("jfidata fail!");22 }23 jfieldID jfcdata = env->GetFieldID(jcSetDataMgr, "cData", "B");24 if(NULL == jfbdata){25 DEBUG_OUT("jfcdata fail!");26 }27 jfieldID jfsdata = env->GetFieldID(jcSetDataMgr, "sData", "Ljava/lang/String;");28 if(NULL == jfbdata){29 DEBUG_OUT("jfsdata fail!");30 }31 32 DEBUG_OUT("Get end!");33 34 env->SetBooleanField(jobj, jfbdata, false);35 DEBUG_OUT("SetBooleanField end!");36 37 env->SetDoubleField(jobj, jfddata, 209.22);38 DEBUG_OUT("SetDoubleField end!");39 40 env->SetIntField(jobj, jfidata, 3653);41 DEBUG_OUT("SetIntField end!");42 43 env->SetByteField(jobj, jfcdata, 67);44 DEBUG_OUT("Set field succ!");45 46 char data[10] = "4611354";47 env->SetObjectField(jobj, jfsdata, env->NewStringUTF(data));48 49 jfieldID jiarr = env->GetFieldID(jcSetDataMgr, "intArr", "[I");50 if(NULL == jiarr){51 DEBUG_OUT("jfbdata fail!");52 }53 54 // 获取Java中数组属性arrays的对象55 jintArray jint_arr = (jintArray)env->GetObjectField(jobj, jiarr);56 57 int arrInt[10] = { 0};58 for(int i = 0; i < 10; ++i){59 arrInt[i] = 220+i;60 }61 env->SetIntArrayRegion(jint_arr, 0, 10, arrInt);62 63 jfieldID jbyteArr = env->GetFieldID(jcSetDataMgr, "byteArr", "[B");64 char arrByte[10] = "20200825";65 jbyteArray jbyte_arr = (jbyteArray)env->GetObjectField(jobj, jbyteArr);66 env->SetByteArrayRegion(jbyte_arr, 0, 8, (const signed char*)arrByte);67 68 DEBUG_OUT("test set data end!");69 70 return NULL;71 }
5,单独讲解:
①查找java类:
jclass jcSetDataMgr = env->FindClass("com/dasea/test/core/TestSetData");
②查找类成员变量:
1 jfieldID jfbdata = env->GetFieldID(jcSetDataMgr, "bData", "Z");2 jfieldID jfddata = env->GetFieldID(jcSetDataMgr, "dData", "D");3 jfieldID jfidata = env->GetFieldID(jcSetDataMgr, "iData", "I");4 jfieldID jfcdata = env->GetFieldID(jcSetDataMgr, "cData", "B");5 jfieldID jfsdata = env->GetFieldID(jcSetDataMgr, "sData", "Ljava/lang/String;");6 jfieldID jbyteArr = env->GetFieldID(jcSetDataMgr, "byteArr", "[B"