JNA 结构中的结构数组
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 我的 class 看起来像这样
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
的映射,但您的问题标题和 this API link matching your structure 表明它是一个嵌套结构数组。必须使用连续内存分配结构数组,方法是直接分配需要知道结构大小的本机内存 (new Memory()
),或者使用 Structure.toArray()
。像您所做的那样在循环中分配最终会为在本机内存中 possibly/probably non-contiguous 位置分配的每个新结构分配内存。鉴于您声明它似乎适用于某些值,您可能对连续分配感到幸运,但您的行为肯定是未定义的。
因此您的结构映射应该是:
@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);
}
我的本机代码是
typedef struct driver_config {
unsigned int dllVersion;
unsigned int channelCount;
unsigned int reserved[10];
ChannelConfig channel[64];
} DriverConfig;
在 Java 我的 class 看起来像这样
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
的映射,但您的问题标题和 this API link matching your structure 表明它是一个嵌套结构数组。必须使用连续内存分配结构数组,方法是直接分配需要知道结构大小的本机内存 (new Memory()
),或者使用 Structure.toArray()
。像您所做的那样在循环中分配最终会为在本机内存中 possibly/probably non-contiguous 位置分配的每个新结构分配内存。鉴于您声明它似乎适用于某些值,您可能对连续分配感到幸运,但您的行为肯定是未定义的。
因此您的结构映射应该是:
@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);
}