我正在创建一个使用JNI的java应用程序。其中一个JNI函数接受枚举作为参数。但是在JNI使用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中的Native代码:
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 :(得分:1)
正如在这些问题中所指出的,NoSuchFieldError通常在使用错误的字段名称调用GetFieldId时发生,即C代码中使用的名称与Java中定义的字段不匹配(包括前面的L,完整包和类名称) ,字段名称和尾随分号):
Get object from an object with JNI in C
正确的通话应该类似于:
jfieldID data = (*env)->GetFieldID(env, some_class, "data", "Lorg/someapp/SomeClass$_data;");
我会仔细检查pConvertTemplate中的代码以查找此类错误 - 或者将其发布给我们进行检查。