В пакете Pragma Pack используется библиотека C, приводящая к сбою jvm

Я использовал C-библиотеку в своем Java-коде, используя JNA. У меня есть эти C-структуры, чьи члены мне нужно печатать на Java. Из-за выравнивания и заполнения памяти размер отличался от того, что я действительно ожидал. Поэтому я использовал прагма-пакет, и так выглядят структуры.

#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) ) PACK( typedef struct { size_t size; uint8_t bytes[48]; } ipj_tid_t); PACK( typedef struct { bool has_epc; //1 ipj_epc_t epc; //64+8 bool has_tid; //1 ipj_tid_t tid; //48+8 bool has_pc; //1 uint32_t pc; //4 bool has_xpc; //1 uint32_t xpc; //4 bool has_crc; //1 uint32_t crc; //4 bool has_timestamp; //1 uint64_t timestamp; //8 bool has_rssi; //1 int32_t rssi; //4 bool has_phase; //1 int32_t phase; //4 bool has_channel; //1 uint32_t channel; //4 bool has_antenna; //1 uint32_t antenna; //4 } ipj_tag); //total size= 174 PACK( typedef struct { bool has_error; ipj_error error; bool has_test_id; uint32_t test_id; bool has_result_1; uint32_t result_1; bool has_result_2; uint32_t result_2; bool has_result_3; uint32_t result_3; size_t data_count; uint32_t data[16]; bool has_timestamp; uint64_t timestamp; size_t lt_buffer_count; uint32_t lt_buffer[21]; } ipj_test_report); PACK( typedef struct { size_t size; uint8_t bytes[64]; } ipj_tag_operation_data_t); PACK( typedef struct { bool has_error; //1 ipj_error error; //4 bool has_tag; //1 ipj_tag tag; //174 bool has_tag_operation_type; //1 ipj_tag_operation_type tag_operation_type; //4 bool has_tag_operation_data; //1 ipj_tag_operation_data_t tag_operation_data; //72 bool has_retries; //1 uint32_t retries; //4 bool has_diagnostic; //1 uint32_t diagnostic; //4 bool has_timestamp; //1 uint64_t timestamp; //8 size_t lt_buffer_count; //8 uint32_t lt_buffer[30]; //120 } ipj_tag_operation_report); //405 

Когда я запускаю код из Visual Studio, я не получаю никаких ошибок, исключений или сбоев от него. Но когда я называю это с Java, jvm рушится. Почему это происходит? В коде C есть и другие структуры, которые не упакованы. Это может быть причина? Пожалуйста посоветуй.

Структуры, которые я показал выше, используются в C. То, что возвращается из кода C, является этой структурой после всей обработки.

 #define RX_MAX_SIZE 405 #pragma pack(push, 1) typedef struct _report { ipj_report_id report_id; uint32_t data_size; uint32_t data[RX_MAX_SIZE]; } report; #pragma pack(pop) 

Эквивалентная структура JNA, которая была использована, выглядит следующим образом.

 public class _report extends Structure { public static class ByValue extends _report implements Structure.ByValue { } public _report() { super(); setAlignType(ALIGN_NONE); } public _ipj_report_id reportid; public int data_size; public int[] data = new int[405]; @Override protected List getFieldOrder() { return Arrays.asList("reportid", "data_size", "data"); } } public class _ipj_report_id extends Structure { public int ipj_report_id; public _ipj_report_id() { super(); setAlignType(ALIGN_NONE); } @Override protected List getFieldOrder() { return Arrays.asList("ipj_report_id"); } } 

Ниже приведена структура, которую я получаю при отладке кода JNA.

  _report$ByValue(auto-allocated@0x18918cc0 (1628 bytes)) { _ipj_report_id reportid@0=_ipj_report_id(allocated@0x18918cc0 (4 bytes) (shared from auto-allocated@0x18918cc0 (1628 bytes))) { int ipj_report_id@0=0 } int data_size@4=195 int data[405]@8=[I@78bb0ecb } 

Ниже я называю этот метод в JNA.

  rfidlib rlib = (rfidlib) Native.loadLibrary("rfidlib", rfidlib.class); _report.ByValue report = new _report.ByValue(); report = rlib.get_next_reports(); 

    JNA предполагает компоновку структуры по умолчанию для текущей целевой платформы (в данном случае, MS-компилятор).

    Вы можете распечатать макет макета памяти, созданного JNA, вызвав Structure.toString() после вызова JVM с помощью -Djna.dump_memory=true .

    Затем вы можете сравнить желаемую структуру структуры с фактическим расположением, созданным JNA, чтобы искать различия. Если вы в целом используете boolean в своей структуре Java, по умолчанию используется выделение собственного int , поэтому, если это не тот же размер, что и ваш собственный bool , вам нужно либо использовать byte на стороне Java, либо явно предоставить TypeMapper для вашей Structure чтобы указывают, что boolean должно быть преобразовано в размер, совместимый с собственным bool (обратите внимание, что размер native bool не определяется стандартом C).

    Я бы рекомендовал не использовать #pragma pack в вашем коде, если вы его явно не нуждаетесь.

    Обновите свой вопрос с помощью своей реализации Java Structure и ее вывода отладки.