这个错,搞了一天才搞定.还是自己对jni不熟.
com.viking.myapplication A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x9c in tid 9502 (g.myapplication).
如果对jni熟悉的话,可能很快就能知道这个错误.但是,如何是刚开始搞jni开发的人来说,可能就一脸懵比了.
这啥玩意啊.
网上搜了很多资料,基本上都是说什么,c代码中存在空指针异常,或者索引越界异常. 反正就是说内存的问题.
在一次无意中搜到tid这个词,thread ID,线程ID? 根据这个思路, 然后一搜,才发现原来,JNIEnv*env 是一个线程对应一个env,线程间不可以共享同一个env变量。
1.首先C代码添加全局变量
JavaVM * vm; //创建javavm的全局变量
2.通过env->GetJavaVM(&vm);来获取javavm指针,保存到vm中. env是当前线程的变量.
3.在新线程中:
JNIEnv *env;
vm->AttachCurrentThread(&env,NULL); //通过vm给env赋值
4.这样在子线程中用env,就行了.
代码:
<1.C主线程初始化
jclass jjnimethodclass; jobject jjnimethodjobject; JavaVM *g_vm = NULL; jmethodID jmethod; jclass jimageuserinfoclazz; jclass jpicinfoclazz ; jmethodID jimageuserinfoID; jmethodID jpicinfoID; jmethodID jregmethod;
JNIEXPORT jint JNICALL Java_com_viking_myapplication_JniMethod_NetInit (JNIEnv *env, jobject jobj){ jjnimethodclass = env->GetObjectClass(jobj); jjnimethodjobject = (jobject)env->NewGlobalRef(jobj); env->GetJavaVM(&g_vm); jclass jimageus = env->FindClass("com/viking/bean/TImageUserInfo"); jclass jpicinfo = env->FindClass("com/viking/bean/TPicInfo"); jimageuserinfoclazz = (jclass)env->NewGlobalRef(jimageus); jpicinfoclazz = (jclass)env->NewGlobalRef(jpicinfo); jimageuserinfoID = env->GetMethodID(jimageuserinfoclazz,"" ,"()V"); jpicinfoID = env->GetMethodID(jpicinfoclazz,"" ,"()V"); jregmethod = env->GetMethodID(jjnimethodclass,"NetRegImageRecvExCallBack","(IILcom/viking/bean/TImageUserInfo;Lcom/viking/bean/TPicInfo;)V"); }
int GetImageCbEx(DCHANDLE tHandle, unsigned int uiImageId, T_ImageUserInfo *ptImageInfo,T_PicInfo *ptPicInfo,void *pUser){ LOGE("GetImageCbEx:回调"); JNIEnv *env2; //g_vm->AttachCurrentThread(&env2, NULL); bool ret = false; if(g_vm != NULL) { JavaVMAttachArgs vmAttachArgs; vmAttachArgs.version = JNI_VERSION_1_6; vmAttachArgs.name = NULL; vmAttachArgs.group = NULL; jint attachRet = g_vm->AttachCurrentThread(&env2, &vmAttachArgs); if(attachRet == 0) { ret = true; } else{ LOGE("attachRet != 0"); ret = false; } } else{ LOGE("g_vm == NULL"); ret = false; } if (ret){ //创建两个对象 jobject jimageuserinfoobj = env2->NewObject(jimageuserinfoclazz,jimageuserinfoID); jobject jpicinfoobj = env2->NewObject(jpicinfoclazz,jpicinfoID); jfieldID usWidthID = env2->GetFieldID(jimageuserinfoclazz,"usWidth","S"); env2->SetShortField(jimageuserinfoobj,usWidthID,ptImageInfo->usWidth); jfieldID usHeightID = env2->GetFieldID(jimageuserinfoclazz,"usHeight","S"); env2->SetShortField(jimageuserinfoobj,usHeightID,ptImageInfo->usHeight); jfieldID ucVehicleColorID = env2->GetFieldID(jimageuserinfoclazz,"ucVehicleColor","B"); env2->SetByteField(jimageuserinfoobj,ucVehicleColorID,ptImageInfo->ucVehicleColor); jfieldID ucVehicleBrandID = env2->GetFieldID(jimageuserinfoclazz,"ucVehicleBrand","B"); env2->SetByteField(jimageuserinfoobj,ucVehicleBrandID,ptImageInfo->ucVehicleBrand); jfieldID ucVehicleSizeID = env2->GetFieldID(jimageuserinfoclazz,"ucVehicleSize","B"); env2->SetByteField(jimageuserinfoobj,ucVehicleSizeID,ptImageInfo->ucVehicleSize); jfieldID ucPlateColorID = env2->GetFieldID(jimageuserinfoclazz,"ucPlateColor","B"); env2->SetByteField(jimageuserinfoobj,ucPlateColorID,ptImageInfo->ucPlateColor); jfieldID szLprResult16ID = env2->GetFieldID(jimageuserinfoclazz,"szLprResult16","[B"); jbyteArray szlprresult16arr = env2->NewByteArray(16); jbyte *szlp = (jbyte*)(ptImageInfo->szLprResult); env2->SetByteArrayRegion(szlprresult16arr,0,16,szlp); env2->SetObjectField(jimageuserinfoobj,szLprResult16ID,szlprresult16arr); jfieldID usLpBox4ID = env2->GetFieldID(jimageuserinfoclazz,"usLpBox4","[S"); jshortArray uslpbox4arr = env2->NewShortArray(4); jshort* uslp = (jshort*)(ptImageInfo->usLpBox); env2->SetShortArrayRegion(uslpbox4arr,0,4,uslp); env2->SetObjectField(jimageuserinfoobj,usLpBox4ID,uslpbox4arr); jfieldID ucLprTypeID = env2->GetFieldID(jimageuserinfoclazz,"ucLprType","B"); env2->SetByteField(jimageuserinfoobj,ucLprTypeID,ptImageInfo->ucLprType); jfieldID usSpeedID = env2->GetFieldID(jimageuserinfoclazz,"usSpeed","S"); env2->SetShortField(jimageuserinfoobj,usSpeedID,ptImageInfo->usSpeed); jfieldID ucSnapTypeID = env2->GetFieldID(jimageuserinfoclazz,"ucSnapType","B"); env2->SetByteField(jimageuserinfoobj,ucSnapTypeID,ptImageInfo->ucSnapType); jfieldID ucReservedID = env2->GetFieldID(jimageuserinfoclazz,"ucReserved","B"); env2->SetByteField(jimageuserinfoobj,ucReservedID,ptImageInfo->ucReserved); jfieldID acSnapTime18ID = env2->GetFieldID(jimageuserinfoclazz,"acSnapTime18","[B"); jbyteArray acsnaptime18arr = env2->NewByteArray(18); jbyte* acsna = (jbyte*)(ptImageInfo->acSnapTime); env2->SetByteArrayRegion(acsnaptime18arr,0,18,acsna); env2->SetObjectField(jimageuserinfoobj,acSnapTime18ID,acsnaptime18arr); jfieldID ucViolateCodeID = env2->GetFieldID(jimageuserinfoclazz,"ucViolateCode","B"); env2->SetByteField(jimageuserinfoobj,ucViolateCodeID,ptImageInfo->ucViolateCode); jfieldID ucLaneNoID = env2->GetFieldID(jimageuserinfoclazz,"ucLaneNo","B"); env2->SetByteField(jimageuserinfoobj,ucLaneNoID,ptImageInfo->ucLaneNo); jfieldID uiVehicleIdID = env2->GetFieldID(jimageuserinfoclazz,"uiVehicleId","I"); env2->SetIntField(jimageuserinfoobj,uiVehicleIdID,ptImageInfo->uiVehicleId); jfieldID ucScoreID = env2->GetFieldID(jimageuserinfoclazz,"ucScore","B"); env2->SetByteField(jimageuserinfoobj,ucScoreID,ptImageInfo->ucScore); jfieldID ucDirectionID = env2->GetFieldID(jimageuserinfoclazz,"ucDirection","B"); env2->SetByteField(jimageuserinfoobj,ucDirectionID,ptImageInfo->ucDirection); jfieldID ucTotalNumID = env2->GetFieldID(jimageuserinfoclazz,"ucTotalNum","B"); env2->SetByteField(jimageuserinfoobj,ucTotalNumID,ptImageInfo->ucTotalNum); jfieldID ucSnapshotIndexID = env2->GetFieldID(jimageuserinfoclazz,"ucSnapshotIndex","B"); env2->SetByteField(jimageuserinfoobj,ucSnapshotIndexID,ptImageInfo->ucSnapshotIndex); //对象二 jfieldID uiPanoramaPicLenID = env2->GetFieldID(jpicinfoclazz,"uiPanoramaPicLen","I"); jint len1 = ptPicInfo->uiPanoramaPicLen; env2->SetIntField(jpicinfoobj,uiPanoramaPicLenID,ptPicInfo->uiPanoramaPicLen); jfieldID uiVehiclePicLenID = env2->GetFieldID(jpicinfoclazz,"uiVehiclePicLen","I"); jint len2 = ptPicInfo->uiVehiclePicLen; env2->SetIntField(jpicinfoobj,uiVehiclePicLenID,ptPicInfo->uiVehiclePicLen); jfieldID ptPanoramaPicBuffID = env2->GetFieldID(jpicinfoclazz,"ptPanoramaPicBuff","[B"); jbyteArray ptpanoramapicbuffstrarr = env2->NewByteArray(len1); jbyte * ptpan = (jbyte*)(ptPicInfo->ptPanoramaPicBuff); env2->SetByteArrayRegion(ptpanoramapicbuffstrarr,0,len1,ptpan); env2->SetObjectField(jpicinfoobj,ptPanoramaPicBuffID,ptpanoramapicbuffstrarr); jfieldID ptVehiclePicBuffID = env2->GetFieldID(jpicinfoclazz,"ptVehiclePicBuff","[B"); jbyteArray ptvehiclepicbuffarr = env2->NewByteArray(len2); jbyte* ptveh = (jbyte*)(ptPicInfo->ptVehiclePicBuff); env2->SetByteArrayRegion(ptvehiclepicbuffarr,0,len2,ptveh); env2->SetObjectField(jpicinfoobj,ptVehiclePicBuffID,ptvehiclepicbuffarr); jstring puser = env2->NewStringUTF((char*)pUser); env2->CallVoidMethod(jjnimethodjobject,jregmethod,tHandle,uiImageId,jimageuserinfoobj,jpicinfoobj); g_vm->DetachCurrentThread(); } else{ LOGE("GetImageCbEx 回调失败."); } return 0; }
<3.注册回调函数
//图片抓拍注册回调接口 1 JNIEXPORT jint JNICALL Java_com_viking_myapplication_JniMethod_NetRegImageRecvEx(JNIEnv *env, jobject jobj, jint tHandle, jstring pUser){ LOGE("Java_com_viking_myapplication_JniMethod_NetRegImageRecvEx"); char *puser = (char*)env->GetStringUTFChars(pUser,0); return Net_RegImageRecvEx(tHandle, GetImageCbEx,(void*)puser); }
<4.回调方法
JNIEXPORT jint JNICALL Java_com_viking_myapplication_JniMethod_NetImageSnap (JNIEnv *env, jobject jobj, jint tHandle,jobject ptImageSnap){ LOGE("Java_com_viking_myapplication_JniMethod_NetImageSnap"); jclass tmp = env->GetObjectClass(jobj); jregimageexclass = (jclass)env->NewGlobalRef(tmp); jregimageexobject = (jobject)env->NewGlobalRef(jobj); T_DCImageSnap t_dcImageSnap; jclass jclazz = env->GetObjectClass(ptImageSnap); jfieldID uiImageIdID = env->GetFieldID(jclazz,"uiImageId","I"); t_dcImageSnap.uiImageId = (unsigned int)env->GetIntField(ptImageSnap,uiImageIdID); jfieldID ucLightIndexID =env->GetFieldID(jclazz,"ucLightIndex","B"); t_dcImageSnap.ucLightIndex = (unsigned char)env->GetByteField(ptImageSnap,ucLightIndexID); jfieldID ucLightModeID =env->GetFieldID(jclazz,"ucLightMode","B"); t_dcImageSnap.ucLightMode =(unsigned char)env->GetByteField(ptImageSnap,ucLightModeID); jfieldID usGroupIdID =env->GetFieldID(jclazz,"usGroupId","S"); t_dcImageSnap.usGroupId =(unsigned short)env->GetShortField(ptImageSnap,usGroupIdID); jint result =Net_ImageSnap(tHandle,&t_dcImageSnap); return result; }
另外这种报错,也可能是空指针或者索引越界异常.(这一点要注意排除);