JNI中Fatal signal 11 (SIGSEGV), code 1的错误.

这个错,搞了一天才搞定.还是自己对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,"<init>","()V");
jpicinfoID = env->GetMethodID(jpicinfoclazz,"<init>","()V");
jregmethod = env->GetMethodID(jjnimethodclass,"NetRegImageRecvExCallBack","(IILcom/viking/bean/TImageUserInfo;Lcom/viking/bean/TPicInfo;)V");
}


<2.回调函数,C辅助线程回调.

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;
}


另外这种报错,也可能是空指针或者索引越界异常.(这一点要注意排除);





阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页