简体   繁体   English

数组中的 JNA 结构内存分配不正确

[英]JNA structure memory allocation in array is incorrect

I have the problem that the memory allocation is incorrect.我有内存分配不正确的问题。 I think so because the bits are shifted between the attributes.我认为是因为位在属性之间移动。

this is the native code:这是本机代码:

typedef struct s_xl_channel_config {
    char                name [32];
    unsigned char       hwType;                               
    unsigned char       hwIndex;                             
    unsigned char       hwChannel;                           
    unsigned short      transceiverType;                     
    unsigned short      transceiverState;                   
    unsigned short      configError;                         
    unsigned char       channelIndex;                       
    unsigned __int64    channelMask;                         
    unsigned int        channelCapabilities;                 
    unsigned int        channelBusCapabilities;                       
    unsigned char       isOnBus;                             
    unsigned int        connectedBusType;                   
    XLbusParams         busParams;
    unsigned int        _doNotUse;                                                                         
    unsigned int        driverVersion;           
    unsigned int        interfaceVersion;                   
    unsigned int        raw_data[10];                   
    unsigned int        serialNumber;
    unsigned int        articleNumber;
    char                transceiverName [32]; 
    unsigned int        specialCabFlags;                     
    unsigned int        dominantTimeout;                     
    unsigned char       dominantRecessiveDelay;             
    unsigned char       recessiveDominantDelay;             
    unsigned char       connectionInfo;                     
    unsigned char       currentlyAvailableTimestamps;         
    unsigned short      minimalSupplyVoltage;                 
    unsigned short      maximalSupplyVoltage;                 
    unsigned int        maximalBaudrate;                     
    unsigned char       fpgaCoreCapabilities;               
    unsigned char       specialDeviceStatus;                 
    unsigned short      channelBusActiveCapabilities;       
    unsigned short      breakOffset;                         
    unsigned short      delimiterOffset;                     
    unsigned int        reserved[3];
} XL_CHANNEL_CONFIG;

My java Code is this:我的java代码是这样的:

@FieldOrder ({"name", "hwType", "hwIndex", "hwChannel", "transceiverType",
  "transceiverState", "configError", "channelIndex", "channelMask", 
  "channelCapabilities", "channelBusCapabilities", "isOnBus", "connectedBusType", 
  "busParams",    "_doNotUse", "driverVersion", "interfaceVersion", "raw_data", 
  "serialNumber", "articleNumber", "transceiverName", "specialCabFlags", 
  "dominantTimeout", "dominantRecessiveDelay", "recessiveDominantDelay", 
  "connectionInfo", "currentlyAvailableTimestamps", "minimalSupplyVoltage", 
  "maximalSupplyVoltage", "maximalBaudrate", "fpgaCoreCapabilities", 
  "specialDeviceStatus", "channelBusActiveCapabilities", "breakOffset", 
  "delimiterOffset", "reserved"})
public class XLchannelConfig extends Structure{

    public byte[] name = new byte[32];
    public byte hwType;
    public byte hwIndex;
    public byte hwChannel;
    public short transceiverType;
    public short transceiverState;
    public short configError;
    public byte channelIndex;
    public Nativelong channelMask;
    public int channelCapabilities;
    public int channelBusCapabilities;
    public byte isOnBus;
    public int connectedBusType;
    public XLbusParams busParams= new XLbusParams();
    public int _doNotUse;
    public int driverVersion;
    public int interfaceVersion;
    public int[] raw_data = new int[(10)];
    public int serialNumber;
    public int articleNumber;
    public byte[] transceiverName = new byte[32];
    public int specialCabFlags;
    public int dominantTimeout;
    public byte dominantRecessiveDelay;
    public byte recessiveDominantDelay;
    public byte connectionInfo;
    public byte currentlyAvailableTimestamps;
    public short minimalSupplyVoltage;
    public short maximalSupplyVoltage;
    public int maximalBaudrate;
    public byte fpgaCoreCapabilities;
    public byte specialDeviceStatus;
    public short channelBusActiveCapabilities;
    public short breakOffset;
    public short delimiterOffset;
    public int[] reserved = new int[3];
    
    public XLchannelConfig() {
        super();        
    }

The XLchannelConfig class is in an array that I initialized with .toArray() . XLchannelConfig 类位于我使用.toArray()初始化的数组中。 When I output the attributes, I see that the values ​​are shifted.当我输出属性时,我看到值发生了变化。 It looks like the bits have shifted from one attribute to the next.看起来这些位已经从一个属性转移到了下一个属性。 I suspect that it is due to the wrong data type, but I cannot determine which it is.我怀疑这是由于错误的数据类型,但我无法确定它是哪个。

The toString print this out: toString 打印出来:

XLchannelConfig [name=Virtual Channel 1               , hwType=1, hwIndex=0, hwChannel=0, transceiverType=0, transceiverState=0, channelIndex=1, channelMask=0, channelCapabilities=458752, channelBusCapabilities=106496, isOnBus=1, connectedBusType=16777216, driverVersion=67830784, interfaceVersion=0, raw_data=[0, 0, 0, 65536, 0, 0, 0, 0, 0, 0], serialNumber=0, articleNumber=536870912, transceiverName=Virtual CAN                    , specialCabFlags=0, dominantTimeout=0, reserved=[0, 0, 1442840576], busParams=XLbusParams [busType=536870912]]

XLchannelConfig [name=irtual Channel 2               , hwType=0, hwIndex=1, hwChannel=22, transceiverType=0, transceiverState=0, channelIndex=0, channelMask=0, channelCapabilities=1792, channelBusCapabilities=16777632, isOnBus=0, connectedBusType=65536, driverVersion=264964, interfaceVersion=0, raw_data=[0, 0, 0, 256, 0, 0, 0, 0, 0, 0], serialNumber=0, articleNumber=1444937728, transceiverName=irtual CAN                    , specialCabFlags=0, dominantTimeout=0, reserved=[0, 0, 0], busParams=XLbusParams [busType=-1591738368]]

The symptoms show an an extra single byte in your mapping.症状在您的映射中显示一个额外的单个字节。 The last element of the reserved field includes the byte 0x56 which corresponds to the letter "V" missing from the second element. reserved字段的最后一个元素包括字节0x56 ,它对应于第二个元素中缺少的字母“V”。 So we need to look for that extra byte.所以我们需要寻找那个额外的字节。

The header file bus types go only up to 0x100 .头文件总线类型最多只能到0x100 Your output has the bus type as 0x20000000 suggesting the error is occurring before the XLbusParams union.您的输出的总线类型为0x20000000表明错误发生在XLbusParams联合之前。 It's definitely occurring before the transcieverName which shows an extra non-null byte as the last character.它肯定发生在transcieverName之前,它显示一个额外的非空字节作为最后一个字符。 Other than channelMask (see below, would be 4-byte offset) the mappings look correct.除了channelMask (见下文,将是 4 字节偏移量)之外,映射看起来是正确的。

One possible mismatch that could explain a single byte could be alignment of the structure fields.可以解释单个字节的一种可能的不匹配可能是结构字段的对齐。 The name takes 32 bytes, and then there are three 1-byte fields followed by three 2-byte fields.该名称占用 32 个字节,然后是三个 1 字节字段,后跟三个 2 字节字段。 This would have one of the short fields crossing a 4-byte or 8-byte boundary.这将使short字段之一跨越 4 字节或 8 字节边界。 You might consider using different JNA Structure alignments, such as Structure.ALIGN_NONE :您可能会考虑使用不同的 JNA 结构对齐方式,例如Structure.ALIGN_NONE

public XLchannelConfig() {
    super(Structure.ALIGN_NONE);
}

Other mapping comments:其他映射注释:

The channelMask field in the C header is an explicit 64-bit type ( int64 ), and thus should be directly mapped to Java's 64-bit long . C 头中的channelMask字段是一个显式的 64 位类型( int64 ),因此应该直接映射到 Java 的 64 位long The only time you should use NativeLong as a mapping is when the native type is long .您应该使用NativeLong作为映射的唯一时间是当本机类型为long This can be either 32-bit or 64-bit, depending on both operating system and bitness.这可以是 32 位或 64 位,具体取决于操作系统和位数。 This would (possibly) under-allocate by 4 bytes, however, and may not be the problem.但是,这会(可能)分配不足 4 个字节,并且可能不是问题。

In copies of the header file in the API, I do not see the _doNotUse field that you include.在 API 头文件的副本中,我没有看到您包含的_doNotUse字段。 Are you sure it should be included?你确定它应该包括在内吗? This adds 4 bytes to the mapping.这为映射增加了 4 个字节。 Are you certain the header file you've copied matches the version of the API binary that you're using?您确定您复制的头文件与您使用的 API 二进制文件的版本匹配吗?

Another potential source of an issue is the XLbusParams type.另一个潜在的问题来源是XLbusParams类型。 The API shows that's a union with an int type and 32 bytes of data. API显示这是一个具有int类型和 32 字节数据的联合。 If you have not properly mapped the union (at least the largest member) that could also cause an offset.如果您没有正确映射也可能导致偏移的联合(至少是最大的成员)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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