在结构中定义JNA结构的例外情况如下:
线程"main“中的
异常java.lang.Error: Structure.getFieldOrder()在com.MyInterface$mine$ByReference类上返回名称(颜色、数据、hello、rice、str、野生),这些名称与声明的字段名不匹配
请参阅我的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的主类包含以下行,其中我对“‘s”结构字段的顺序有异常:
final MyInterface.mine.ByReference mine_ref = new MyInterface.mine.ByReference();
因此,我调试代码,以便在Structure.class之后逐步进入JNA,进入以下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。因为我的字段顺序是通过new HashSet<String>(fieldOrder)
指令随机排序的,因此不同于orderedNames的顺序。
如果没有bug,
发布于 2020-11-14 19:12:57
您的错误在mine
结构中:您需要将字段声明为public
。JNA使用反射,对于要映射到本机的字段依赖public
修饰符;否则它们只是类中的助手字段。
否则,映射将以您拥有的方式工作,但请考虑以下改进:
ByValue
版本。这是默认的。唯一需要使用嵌套结构的特殊操作是如果它是ByReference
。ByReference
是默认的。只有当函数需要ByValue
参数时,才需要特殊的ByValue
参数。@FieldOrder
注释替换了getFieldOrder()
覆盖的使用。虽然您所拥有的可以工作,但是如果您只是将注释放在结构的前面,例如,则代码的可读性更强。
@FieldOrder({"data", "size"})
class his extends Structure {
// etc...
}
默认情况下,
public
、static
和final
,因此使用这些修饰符是多余的。https://stackoverflow.com/questions/64835834
复制相似问题