[英]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.