2013-08-06 45 views
2

我正在創建一個使用JNI的java應用程序。其中一個JNI函數接受枚舉作爲參數。但是在JNI使用參數java顯示java.lang.NoSuchFieldError之後。java中的java.lang.NoSuchFieldError錯誤

這裏的java代碼:

private int convert(JacsbclibLoader.BCTemplateEnvelopeType inputTemplateEnvelopeType,  JacsbclibLoader.BCTemplateDataType inputTemplateDataType, JacsbclibLoader.BCTemplateEnvelopeType outputTemplateEnvelopeType, JacsbclibLoader.BCTemplateDataType outputTemplateDataType, byte[] inputData, byte[] outputData, JacsbclibLoader.BCTemplateInfoType_1 suplementaryInfo) 
{ 

    if(outputData != null) 
     outputLength = outputData.length; 

    status = _bclib.jBCConvertTemplate(inputTemplateEnvelopeType, inputTemplateDataType,inputData, inputData.length, outputTemplateEnvelopeType,         outputTemplateDataType, outputData, outputLength, suplementaryInfo); 
    return status; 
} 

以下是一個Java本機代碼:

public enum BCTemplateDataType 
{ 
    BCT_NOT_SPECIFIED(-1), 
    BCT_NONE(0), 
    BCT_UPEK_LEGACY(1), 
    BCT_UPEK_ALPHA(2), 
    BCT_UPEK_BETA(3), 
    BCT_UPEK_AUTO(4), 
    BCT_ANSI(5), 
    BCT_ISO_FMR(6), 
    BCT_ISO_FMC_NORMAL(7), 
    BCT_ISO_FMC_COMPACT(8), 
    BCT_ABAPI(9), 
    BCT_LAST(10); 

    private int value; 

    private BCTemplateDataType(int value) 
    { 
     this.value = value; 
    } 
} 

public int jBCConvertTemplate(BCTemplateEnvelopeType inputEnvelopeType, 
            BCTemplateDataType inputDataType, 
            byte[] inputData, 
            int inputDataLength, 
            BCTemplateEnvelopeType outputEnvelopeType, 
            BCTemplateDataType outputDataType, 
            byte[] outputData, 
            int outputDataLength, 
            BCTemplateInfoType_1 suplementaryInfo) 
    { 
     ret = BCConvertTemplate(inputEnvelopeType, inputDataType, inputData, inputDataLength, outputEnvelopeType, outputDataType, outputData, outputDataLength, suplementaryInfo); 
     return ret; 
    }; 

    private native int BCConvertTemplate(BCTemplateEnvelopeType inputEnvelope, 
             BCTemplateDataType inputDataType, 
             byte[] input, 
             int inputLength, 
             BCTemplateEnvelopeType outputEnvelope, 
             BCTemplateDataType outputDataType, 
             byte[] output, 
             int outputLength, 
             BCTemplateInfoType_1 suplementaryInfo); 

這裏是C++中的JNI代碼:

JNIEXPORT jint JNICALL Java_JacsbclibLoader_BCConvertTemplate 
    (JNIEnv *env, jobject obj, jobject inputEnvelope, jobject inputDataType, jbyteArray inputData, jint inputLength, jobject outputEnvelope, jobject outputDataType, jbyteArray outputData, jint outputLength, jobject suplementaryInfo) 
{ 
    LoadLib(); 


    BCTemplateInfoType_1 supInfo; 


    BCTemplateEnvelopeType eInputTemplateEnvelopeType = BCTE_NONE; 
    BCTemplateEnvelopeType eOutputTemplateEnvelopeType = BCTE_NONE; 

    BCTemplateDataType eInputTemplateDataType = BCT_NONE; 
    BCTemplateDataType eOutputTemplateDataType = BCT_NONE; 


    jbyte *inputTemplate = env->GetByteArrayElements(inputData, 0); 
    jbyte *outputTemplate = NULL; 

    if(outputData != NULL) 
    { 
     MessageBox(NULL,"outputData != NULL","",0); 
     jbyte *outputTemplate = env->GetByteArrayElements(outputData, 0); 
    } 



    jclass cls = env->GetObjectClass(obj); 
    jfieldID fIdInputLength = env->GetStaticFieldID(cls, "inputLength", "I"); 
    jfieldID fIdOutputLength = env->GetStaticFieldID(cls, "outputLength", "I"); 


    if(pConvertTemplate) 
    { 


     /*int inputEnvelopeType; 
     int inputEnvelopeDataType; 
     int outputEnvelopeType; 
     int outputEnvelopeDataType;*/ 

     /*jclass envelopeTypeClass = env->FindClass("JacsbclibLoader"); 
     MessageBox(NULL,"3.1","",0); 
     jmethodID inputEnvelopeGetValueMethod = env->GetMethodID(envelopeTypeClass, "getValue", "I()"); 
     MessageBox(NULL,"3.2","",0); 
     jint inputEnvelopeValue = env->CallIntMethod(inputEnvelope, inputEnvelopeGetValueMethod); 

     MessageBox(NULL,"3.3","",0); 
     eInputTemplateEnvelopeType = (BCTemplateEnvelopeType)inputEnvelopeValue; 
     MessageBox(NULL,"3.4","",0);*/ 

     jclass inputEnvelopeClass = env->GetObjectClass(inputEnvelope); 
     jclass inputEnvelopeDataTypeClass = env->GetObjectClass(inputDataType); 
     jclass outputEnvelopeClass = env->GetObjectClass(outputEnvelope); 
     jclass outputEnvelopeDataTypeClass = env->GetObjectClass(outputDataType); 

     if(suplementaryInfo != NULL) 
     { 
      MessageBox(NULL,"4","",0); 

      int ver; 
      int captureCbeffpId; 
      int captureEquiptCompliance; 
      int captureEquiptId; 
      int imgWidth; 
      int imgHeight; 
      int imgHorizontalResolution; 
      int imgVerticalResolution; 
      int fingerPos; 

      jclass suplementaryClass = env->GetObjectClass(suplementaryInfo); 

      jfieldID fIdVersion = env->GetFieldID(suplementaryClass, "version", "I"); 
      jfieldID fIdCaptureCbeffpid = env->GetFieldID(suplementaryClass, "captureCBEFFPid", "I"); 
      jfieldID fIdCaptureEquipmentCompliance = env->GetFieldID(suplementaryClass, "captureEquipmentCompliance", "I"); 
      jfieldID fIdCaptureEquipmentId = env->GetFieldID(suplementaryClass, "captureEquipmentId", "I"); 
      jfieldID fIdImageWidth = env->GetFieldID(suplementaryClass, "imageWidth", "I"); 
      jfieldID fIdImageHeigth = env->GetFieldID(suplementaryClass, "imageHeight", "I"); 
      jfieldID fIdImageHorizontalResolution = env->GetFieldID(suplementaryClass, "imageHorizontalResolution", "I"); 
      jfieldID fIdImageVerticalResolution = env->GetFieldID(suplementaryClass, "imageVerticalResolution", "I"); 
      jfieldID fIdFingerPosition = env->GetFieldID(suplementaryClass, "fingerPosition", "I"); 

      ver = env->GetIntField(suplementaryInfo, fIdVersion); 
      captureCbeffpId = env->GetIntField(suplementaryInfo, fIdCaptureCbeffpid); 
      captureEquiptCompliance = env->GetIntField(suplementaryInfo, fIdCaptureEquipmentCompliance); 
      captureEquiptId = env->GetIntField(suplementaryInfo, fIdCaptureEquipmentId); 
      imgWidth = env->GetIntField(suplementaryInfo, fIdImageWidth); 
      imgHeight = env->GetIntField(suplementaryInfo, fIdImageHeigth); 
      imgHorizontalResolution = env->GetIntField(suplementaryInfo, fIdImageHorizontalResolution); 
      imgVerticalResolution = env->GetIntField(suplementaryInfo, fIdImageVerticalResolution); 
      fingerPos = env->GetIntField(suplementaryInfo, fIdFingerPosition); 

      memset(&suplementaryInfo, 0x00, sizeof(suplementaryInfo)); 

      supInfo.version = ver; 
      supInfo.captureCBEFFPid = captureCbeffpId; 
      supInfo.captureEquipmentCompliance = captureEquiptCompliance; 
      supInfo.captureEquipmentId = captureEquiptId; 
      supInfo.fingerPosition = fingerPos; 
      supInfo.imageHeight = imgHeight; 
      supInfo.imageHorizontalResolution = imgHorizontalResolution; 
      supInfo.imageVerticalResolution = imgVerticalResolution; 
      supInfo.imageWidth = imgWidth; 

     } 

     returnStatus = pConvertTemplate(eInputTemplateEnvelopeType, 
             eInputTemplateDataType, (const void *)inputTemplate, (uint32)inputLength, 
             eOutputTemplateEnvelopeType, 
             eOutputTemplateDataType, 
             outputData != NULL ? (void *)outputTemplate : NULL,          
             (uint32 *)&outputLength, 
             suplementaryInfo != NULL ? (const void *)&supInfo : NULL); 

     env->SetStaticIntField(cls, fIdOutputLength, outputLength); // It also crashes in windows7 

     return returnStatus; 

    } 
    else 
     return returnStatus; 
} 

和這裏的枚舉其中JNI提到的第三方庫:typedef enum _tag_BCTemplateDataType { BCT_NOT_SPECIFIED = -1,
BCT_NONE = 0,
BCT_UPEK_LEGACY,
BCT_UPEK_ALPHA,
BCT_UPEK_BETA,
BCT_UPEK_AUTO,
BCT_ANSI,
BCT_ISO_FMR,
BCT_ISO_FMC_NORMAL,
BCT_ISO_FMC_COMPACT,
BCT_ABAPI,
BCT_LAST
} BCTemplateDataType;

+0

是'status = _bclib.jBCConvertTemplate(inputTemplateEnvelopeType,inputTemplateDataType,inputData,inputData.length,outputTemplateEnvelopeType,outputTemplateDataType,outputData,outputLength,suplementaryInfo)引發的異常;'? – FrancescoDS

+0

該函數後拋出異常。請注意,之後沒有任何命令。 – BebzSusuma

+0

pConvertTemplate做什麼? – Joni

回答

0

正如在這些問題中指出的那樣,當調用帶有錯誤字段名稱的GetFieldId時,通常會發生NoSuchFieldError,即C代碼中使用的名稱與Java中定義的字段不匹配(包括前面的L,完整的包名和類名,字段名和結尾的分號):

JNI: NoSuchFieldError

Get object from an object with JNI in C

正確的調用應該是這個樣子:

jfieldID data = (*env)->GetFieldID(env, some_class, "data", "Lorg/someapp/SomeClass$_data;"); 

我會仔細檢查pConvertTemplate中的代碼是否有這種類型的錯誤 - 或者發佈給我們檢查。

+0

我修改了上面的代碼以顯示JNI函數的全部內容 – BebzSusuma

+0

GetFieldId調用應該看起來更像這樣:jfieldID data =(* env) - > GetFieldID(env,some_class,「data」,「Lorg/someapp/SomeClass $ _data;「); –

+0

我嘗試過,但沒有運氣 – BebzSusuma

相關問題