KNI接口 "KNI_GetFieldID" 调用失败问题的解决


KNI接口 "KNI_GetFieldID" 调用失败问题的解决


每次调用KNI_GetFieldID总是返回0,也就是在函数_KNI_field_lookup_helper()中执行到如下代码片段:

  if (!field.is_valid() || (field.is_static() != is_static) ||
      // We do not support field IDs in super classes:
      (field.is_static() && !holder().equals(&ic))) {
    return (jfieldID)0;


然而在 kni.h 中有这么一段注释:

/**
 * Instance field access.
 *
 * Note specific to this VM: KNI_GetFieldID() must not be applied
 * on a class whose
 * fields have been renamed by the romizer. You need to use
 * the DontRenameNonPublicFields flag in your romizer configuration
 * file. See src/vm/cldc_rom.cfg in this VM source distribution
 * for an example.
 */
KNIEXPORT jfieldID KNI_GetFieldID(jclass classHandle, const char* name,
                       const char* signature);

也就是说 class 的 fields 会被 romizer 改名,而KNI_GetFieldID对改名后的 fields 会获取失败;
为避免 fields 被改名,需要在cldc/src/vm/cldc_rom.cfg 中使用DontRenameNonPublicFields,如下:

# Do not rename the non-public fields/methods of the following classes,
# because these fields are accessed by name in KNI code.
DontRenameNonPublicFields = com.eastcom.eui.entity.Contact
DontRenameNonPublicFields = com.sun.cldc.io.ResourceInputStream
If CLDC_11
DontRenameNonPublicFields = java.lang.ref.WeakReference
EndIf
#Some symbols are referenced during bootstrap to verify the class
If ISOLATES
DontRenameNonPublicFields = com.sun.cldc.isolate.Isolate
DontRenameNonPublicMethods = com.sun.cldc.isolate.Isolate
EndIf

修改后验证,KNI_GetFieldID 获取成功。

结论就是KNI对应的JAVA上层实体类的成员一般最好定义成public的,如果是private,

需要修改cldc/src/vm/cldc_rom.cfg文件。



PS: 从字面上理解DontRenameNonPublicFields,private域会被修改,而public域是否不会被改名呢?
KNI_GetFieldID 对 public域是否能总是获取成功?此猜想待验证(不会改名)


你可能感兴趣的:(KNI接口 "KNI_GetFieldID" 调用失败问题的解决)