#java #structure #jna #allocation
#java #структура #jna #распределение
Вопрос:
структура в моем машинном коде:
struct s_xl_daio_data { /* 32 Bytes */
unsigned short flags; // 2
unsigned int timestamp_correction; // 4
unsigned char mask_digital; // 1
unsigned char value_digital; // 1
unsigned char mask_analog; // 1
unsigned char reserved0; // 1
unsigned short value_analog[4]; // 8
unsigned int pwm_frequency; // 4
unsigned short pwm_value; // 2
unsigned int reserved1; // 4
unsigned int reserved2; // 4
};
мой класс Java:
@FieldOrder ({"flags", "timestamp_correction", "mask_digital",
"value_digital", "mask_analog", "reserved0", "value_analog",
"pwm_frequency", "pwm_value", "reserved1", "reserved2"})
public class s_xl_daio_data extends Structure {
public short flags; // 2
public int timestamp_correction; // 4
public byte mask_digital; // 1
public byte value_digital; // 1
public byte mask_analog; // 1
public byte reserved0; // 1
public short[] value_analog= new short[4]; // 8
public int pwm_frequency; // 4
public short pwm_value; // 2
public int reserved1; // 4
public int reserved2; // 4
public s_xl_daio_data() {
super();
}
}
Собственная структура составляет 32 байта. Если я распечатаю размер структуры с .size()
помощью операции из Structure, он составит 36 байт.
Каковы 4 дополнительных байта?
Ответ №1:
Сопоставления верны, но выравнивания структуры по умолчанию создают дополнительное заполнение в JNA, которое предполагает значения по умолчанию, если не указано иное.
Способ подтвердить это и отладить будущие несоответствия размера / выравнивания структуры — использовать Structure
toString()
метод класса по умолчанию. Он выводит смещение и значение каждого поля, поэтому вы можете искать несоответствие смещений вашим ожиданиям.
s_xl_daio_data foo = new s_xl_daio_data();
System.out.println(foo.toString());
Проверка вывода этого кода в моей системе показывает два дополнительных байта после первого short
, потому int timestamp_correction
что должно начинаться с 4-байтовой границы (0x4, а не 0x2):
short flags@0x0=0x00
int timestamp_correction@0x4=0x0000
и еще два дополнительных байта после последнего short
, потому int reserved1
что должны начинаться с 4-байтовой границы (0x1C, а не 0x1A):
short pwm_value@0x18=0x00
int reserved1@0x1C=0x0000
Выравнивание по умолчанию часто работает с системными библиотеками DLL, которые во многих случаях учитывают выравнивание структуры с помощью явных полей заполнения. Однако иногда другие библиотеки DLL не требуют выравнивания, и в этом случае вы должны указать это в JNA при создании экземпляра структуры.
public s_xl_daio_data() {
super(Structure.ALIGN_NONE);
}
Было бы полезно подтвердить, что это дает вам ожидаемые данные в соответствующих полях, используя то же toString()
самое, что указано ранее.