![](/img/trans.png)
[英]Invalid memory access with JNA reading from an array of structures inside a structure
[英]Array of structures in a structure in JNA
我的本机代码是
typedef struct driver_config {
unsigned int dllVersion;
unsigned int channelCount;
unsigned int reserved[10];
ChannelConfig channel[64];
} DriverConfig;
在 Java 中,我的类看起来像这样
public class DriverConfig extends Structure {
public int dllVersion;
public int channelCount;
public int[] reserved= new int[10];
ChannelConfig[] channel = new ChannelConfig[64];
public DriverConfig() {
super();
init();
}
private void init() {
for (int i = 0; i < channel.length; i++) {
channel[i]= new ChannelConfig();
}
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "dllVersion", "channelCount", "reserved" });
}
//toString()...
}
方法声明是
int getDriverConfig(DriverConfig driverConfig);
我试图访问这样的方法
DriverConfig driverConfig = new DriverConfig();
status = dll.INSTANCE.getDriverConfig(driverConfig);
System.out.println("DriverConfig Status: " + status);
System.out.println(driverConfig.toString());
如果channel.length
被替换为小于 50,则数组被正确初始化,但channel.length
不起作用。 它甚至没有显示任何错误。
您的getFieldOrder()
数组不包括结构的最后一个元素 ( channel
)。 我在您的评论中看到您尝试执行此操作但收到错误,因为您尚未将其声明为public
。 结构中的所有元素都必须列在FieldOrder
,并声明为public
以便可以通过反射找到它们。
此外,对于 JNA 5.x(您应该使用), @FieldOrder
注释是首选。
您尚未确定ChannelConfig
的映射,但您的问题标题和与您的结构匹配的此 API 链接表明它是一个嵌套结构数组。 结构数组必须使用连续内存分配,或者通过直接分配需要知道结构大小的本机内存( new Memory()
),或者使用Structure.toArray()
。 像您所做的那样在循环中分配最终会为在本机内存中可能/可能不连续的位置分配的每个新结构分配内存。 鉴于您声明它似乎适用于某些值,您可能会因为连续分配而幸运,但您的行为肯定是未定义的。
因此,您的结构映射应该是:
@FieldOrder ({"dllVersion", "channelCount", "reserved", "channel"})
public class DriverConfig extends Structure {
public int dllVersion;
public int channelCount;
public int[] reserved= new int[10];
public ChannelConfig[] channel = (ChannelConfig[]) new ChannelConfig().toArray(64);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.