![](/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.