Reputation: 147
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:
@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()
.
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:
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]]
Upvotes: 1
Views: 275
Reputation: 9131
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. So we need to look for that extra byte.
The header file bus types go only up to 0x100
. Your output has the bus type as 0x20000000
suggesting the error is occurring before the XLbusParams
union. It's definitely occurring before the transcieverName
which shows an extra non-null byte as the last character. Other than channelMask
(see below, would be 4-byte offset) the mappings look correct.
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. This would have one of the short
fields crossing a 4-byte or 8-byte boundary. You might consider using different JNA Structure alignments, such as 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
. The only time you should use NativeLong
as a mapping is when the native type is long
. This can be either 32-bit or 64-bit, depending on both operating system and bitness. This would (possibly) under-allocate by 4 bytes, however, and may not be the problem.
In copies of the header file in the API, I do not see the _doNotUse
field that you include. Are you sure it should be included? This adds 4 bytes to the mapping. Are you certain the header file you've copied matches the version of the API binary that you're using?
Another potential source of an issue is the XLbusParams
type. The API shows that's a union with an int
type and 32 bytes of data. If you have not properly mapped the union (at least the largest member) that could also cause an offset.
Upvotes: 2