我在结构中定义jna结构时遇到以下异常:
线程“main”java.lang.error中出现异常:类com.myinterface$mine$byreference上的structure.getfieldorder()返回与声明的字段名不匹配的名称([color,data,hello,rice,str,wild])
查看我的cpp结构:
typedef struct s_mine
{
e_color color; //e_color is enum type made of int values
his data;
int str;
unsigned int wild;
unsigned int hello;
float rice;
} mine;
typedef struct s_his
{
unsigned char * data;
unsigned int size;
} his;
请参见下面的示例,即myinterface.java:
public interface MyInterface extends Library {
public static class his extends Structure {
public static class ByReference extends his implements Structure.ByReference {} // Need the stucture address as it a parameter of a particular wrapped method
public static class ByValue extends his implements Structure.ByValue {} // Need the structure value inside "mine" Structure
public Pointer data;
public int size;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "data", "size"});
}
}
public class mine extends Structure {
public static class ByReference extends mine implements Structure.ByReference {}
int color;
his.ByValue data;
int str;
int wild;
int hello;
float rice;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] {"color","data","str","wild","hello","rice"});
}
}
}
使用myinterface的主类包含以下行,在该行上我有一个关于“mine”结构字段顺序的异常:
final MyInterface.mine.ByReference mine_ref = new MyInterface.mine.ByReference();
因此,我调试代码,以便将jna以下structure.class步进以下getfields方法(在其中我得到异常(下面的第二个异常):
protected List<Field> getFields(boolean force) {
List<Field> flist = getFieldList();
Set<String> names = new HashSet<String>();
for (Field f : flist) {
names.add(f.getName());
}
List<String> fieldOrder = fieldOrder();
if (fieldOrder.size() != flist.size() && flist.size() > 1) {
if (force) {
throw new Error("Structure.getFieldOrder() on " + getClass()
+ (fieldOrder.size() < flist.size()
? " does not provide enough"
: " provides too many")
+ " names [" + fieldOrder.size()
+ "] ("
+ sort(fieldOrder)
+ ") to match declared fields [" + flist.size()
+ "] ("
+ sort(names)
+ ")");
}
return null;
}
Set<String> orderedNames = new HashSet<String>(fieldOrder);
if (!orderedNames.equals(names)) {
throw new Error("Structure.getFieldOrder() on " + getClass()
+ " returns names ("
+ sort(fieldOrder)
+ ") which do not match declared field names ("
+ sort(names) + ")");
}
sortFields(flist, fieldOrder);
return flist;
}
这是当getfields方法中引发异常时,我在探索以下字段值时得到的结果
fieldOrder = [color, data, str, wild, hello, rice]
orderedNames = [str, color, data, hello, rice, wild]
由于名称为空,引发了异常。无论如何,由于hashset java.util类不能保证随着时间的推移顺序保持不变,我肯定认为jna structure.java中存在bug。因为我的fieldorder的顺序是按照 new HashSet<String>(fieldOrder)
指令,因此不同于orderednames的顺序。
有没有人同意我的观点,或者我遗漏了一些关于如何声明和使用我的jna结构的内容?
如果没有bug(即hashset是故意使用的……),那么我是否在声明我的结构时出错了?我如何解决这个问题?
1条答案
按热度按时间emeijp431#
你的错误在
mine
结构:需要将字段声明为public
. jna使用反射并依赖于public
要Map到本机的字段的修饰符;否则,它们只是类中的助手字段。否则,Map将按您的方式工作,但请考虑以下改进:
你不需要使用
ByValue
用作嵌套结构时的结构版本。这是默认值。唯一需要对嵌套结构执行特殊操作的时间是ByReference
.同样地,
ByReference
是用作函数参数时的默认值。仅当函数需要ByValue
它是否需要特殊处理。使用
getFieldOrder()
在jna 5.x中,重写被替换为@FieldOrder
注解。当你所拥有的东西起作用的时候,如果你只是把注解放在你的结构之前,你的代码更可读,例如。,默认情况下,接口变量/类/等
public
,static
,和final
所以使用这些修饰语是多余的。