简体   繁体   English

JNA中结构中的结构数组

[英]Array of structures in a structure in JNA

My native code is我的本机代码是

typedef struct driver_config {
    unsigned int dllVersion;
    unsigned int channelCount;
    unsigned int reserved[10];
    ChannelConfig channel[64];
} DriverConfig;

In Java my class looks like this在 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()...
}

The method declaration is方法声明是

int getDriverConfig(DriverConfig driverConfig);

I tried to access the method like this我试图访问这样的方法

DriverConfig driverConfig = new DriverConfig();
status = dll.INSTANCE.getDriverConfig(driverConfig);
System.out.println("DriverConfig Status: " + status);
System.out.println(driverConfig.toString());

If channel.length is replaced with less then 50 the array is initialized correctly but with channel.length it did not work.如果channel.length被替换为小于 50,则数组被正确初始化,但channel.length不起作用。 It even did not show any error just nothing.它甚至没有显示任何错误。

Your getFieldOrder() array does not include the last element ( channel ) of your structure.您的getFieldOrder()数组不包括结构的最后一个元素 ( channel )。 I see in your comments that you attempted to do this but received an error because you have not declared it public .我在您的评论中看到您尝试执行此操作但收到错误,因为您尚未将其声明为public All elements of your structure must be listed in the FieldOrder and also declared public so they can be found with reflection.结构中的所有元素都必须列在FieldOrder ,并声明为public以便可以通过反射找到它们。

Also, with JNA 5.x (which you should be using) the @FieldOrder annotation is preferred.此外,对于 JNA 5.x(您应该使用), @FieldOrder注释是首选。

You haven't identified the mapping for ChannelConfig , but your question title and this API link matching your structure indicate that it is a nested structure array.您尚未确定ChannelConfig的映射,但您的问题标题和与您的结构匹配的此 API 链接表明它是一个嵌套结构数组。 Structure arrays must be allocated using contiguous memory, either by directly allocating the native memory ( new Memory() ) which requires knowing the structure size, or by using Structure.toArray() .结构数组必须使用连续内存分配,或者通过直接分配需要知道结构大小的本机内存( new Memory() ),或者使用Structure.toArray() Allocating in a loop as you have done will end up with memory for each new structure allocated at possibly/probably non-contiguous locations in native memory.像您所做的那样在循环中分配最终会为在本机内存中可能/可能不连续的位置分配的每个新结构分配内存。 Given that you state that it appears to work for some values, you might be getting lucky with contiguous allocations, but your behavior is certainly undefined.鉴于您声明它似乎适用于某些值,您可能会因为连续分配而幸运,但您的行为肯定是未定义的。

Your structure mapping should therefore be:因此,您的结构映射应该是:

@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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM